@reboot-dev/reboot 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "@bufbuild/protobuf": "1.3.2",
4
4
  "@bufbuild/protoplugin": "1.3.2",
5
5
  "@bufbuild/protoc-gen-es": "1.3.2",
6
- "@reboot-dev/reboot-api": "0.22.0",
6
+ "@reboot-dev/reboot-api": "0.23.0",
7
7
  "chalk": "^4.1.2",
8
8
  "node-addon-api": "^7.0.0",
9
9
  "node-gyp": ">=10.2.0",
@@ -14,7 +14,7 @@
14
14
  },
15
15
  "type": "module",
16
16
  "name": "@reboot-dev/reboot",
17
- "version": "0.22.0",
17
+ "version": "0.23.0",
18
18
  "description": "npm package for Reboot",
19
19
  "scripts": {
20
20
  "postinstall": "rbt || exit 0",
@@ -64,6 +64,7 @@
64
64
  "exports": {
65
65
  "./package.json": "./package.json",
66
66
  ".": "./index.js",
67
+ "./secrets": "./secrets/index.js",
67
68
  "./utils": "./utils/index.js"
68
69
  }
69
70
  }
package/rbt.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { spawnSync } from "child_process";
2
+ import { spawn } from "child_process";
3
3
  import * as path from "path";
4
4
  import whichPMRuns from "which-pm-runs";
5
5
  import { ensureYarnNodeLinker } from "./utils/index.js";
@@ -43,14 +43,25 @@ async function main() {
43
43
  process.env.RBT_FROM_NODEJS = "true";
44
44
  // Add extensionless loader.
45
45
  addExtensionlessToNodeOptions();
46
- const rbt = spawnSync(`${path.join(VENV_EXEC_PATH, "rbt")} ${process.argv.slice(2).join(" ")}`, {
46
+ // Using 'spawn' instead of 'spawnSync' to avoid blocking the event loop for
47
+ // signal handling.
48
+ const rbt = spawn(`${path.join(VENV_EXEC_PATH, "rbt")} ${process.argv.slice(2).join(" ")}`, {
47
49
  stdio: [process.stdin, process.stdout, process.stderr],
48
50
  shell: true,
49
51
  });
50
- if (rbt.error) {
51
- throw new Error(`Unable to execute 'rbt', please report this bug to the maintainers!\n${rbt.error}`);
52
- }
53
- process.exit(rbt.status);
52
+ process.on("SIGINT", () => {
53
+ // Make sure to kill the child process before exiting.
54
+ rbt.once("exit", (code) => {
55
+ process.exit(code);
56
+ });
57
+ });
58
+ rbt.on("exit", (code) => {
59
+ // If the child process exits with a non-zero code, exit with the same code.
60
+ process.exit(code ?? 1);
61
+ });
62
+ rbt.on("error", (error) => {
63
+ throw new Error(`Unable to execute 'rbt', please report this bug to the maintainers!\n${error}`);
64
+ });
54
65
  }
55
66
  main().catch((error) => {
56
67
  console.error(error instanceof Error ? error.message : error);
package/reboot_native.cc CHANGED
@@ -32,6 +32,40 @@ struct PythonNodeAdaptor {
32
32
  // static instance of `PythonNodeAdaptor`.
33
33
  void Initialize(Napi::Env& env, const Napi::Function& js_callback);
34
34
 
35
+ static void HandleException(const std::exception& e) {
36
+ // First determine if the exception was thrown from Python or C++.
37
+ if (const py::error_already_set* e_py =
38
+ dynamic_cast<const py::error_already_set*>(&e)) {
39
+ // This is a Python exception. Is it an `InputError`?
40
+ if (e_py->matches(py::module::import(
41
+ "reboot.controller.exceptions")
42
+ .attr("InputError"))) {
43
+ // This is an InputError, which means it reports a mistake in the input
44
+ // provided by the developer. We want to print _only_ the user-friendly
45
+ // error message in the exception, without intimidating stack traces.
46
+ //
47
+ // Calling `e_py->what()` would produce a stack trace, so we get only
48
+ // the user-friendly message by stringifying in Python-land instead.
49
+ std::string what = py::str(e_py->value());
50
+ std::cerr << what << std::endl;
51
+ } else {
52
+ // This is an internal error from the Python library. Request that the
53
+ // developer reports the issue, and give them the full stack trace to
54
+ // help diagnose the problem.
55
+ std::cerr << "Unexpected library exception: " << e_py->what()
56
+ << std::endl
57
+ << "Please report this bug to the maintainers!"
58
+ << std::endl;
59
+ }
60
+ } else {
61
+ // This is a C++ exception; something went wrong in the C++ code. Request
62
+ // that the developer reports the issue.
63
+ std::cerr
64
+ << "Unexpected adapter exception: " << e.what() << std::endl
65
+ << "Please report this bug to the maintainers!" << std::endl;
66
+ }
67
+ }
68
+
35
69
  template <typename F>
36
70
  void ScheduleCallbackOnPythonEventLoop(F&& f) {
37
71
  auto function = [f = std::forward<F>(f)]() mutable {
@@ -54,11 +88,7 @@ struct PythonNodeAdaptor {
54
88
  try {
55
89
  f(env);
56
90
  } catch (const std::exception& e) {
57
- std::cerr
58
- << "Unexpected exception: " << e.what()
59
- << "\n"
60
- << "Please report this bug to the maintainers!"
61
- << std::endl;
91
+ PythonNodeAdaptor::HandleException(e);
62
92
  }
63
93
  });
64
94
 
@@ -208,12 +238,8 @@ void PythonNodeAdaptor::Initialize(
208
238
  py::cpp_function([function = std::move(function)]() {
209
239
  try {
210
240
  function();
211
- } catch (std::exception& e) {
212
- std::cerr
213
- << "Unexpected exception: " << e.what()
214
- << "\n"
215
- << "Please report this bug to the maintainers!"
216
- << std::endl;
241
+ } catch (const std::exception& e) {
242
+ PythonNodeAdaptor::HandleException(e);
217
243
  }
218
244
  }));
219
245
  }
@@ -1522,7 +1548,9 @@ Napi::Value Service_constructor(const Napi::CallbackInfo& info) {
1522
1548
  .attr("_Schedule");
1523
1549
  promise.set_value(
1524
1550
  new py::object(py_module.attr(node_adaptor.c_str())(
1525
- id,
1551
+ // The call will stay within the same application.
1552
+ "application_id"_a = py::none(),
1553
+ "state_id"_a = id,
1526
1554
  "schedule_type"_a = py_schedule_type)));
1527
1555
  });
1528
1556
 
package/venv.js CHANGED
@@ -45,6 +45,11 @@ function pipInstallReboot() {
45
45
  }
46
46
  }
47
47
  export function ensurePythonVenv() {
48
+ // If the virtual environment is already activated, do not attempt to
49
+ // re-create it.
50
+ if (process.env.VIRTUAL_ENV === VENV_PATH) {
51
+ return;
52
+ }
48
53
  // Ensure that the Docker base Reboot image version and the Reboot
49
54
  // version are in sync.
50
55
  if (process.env.REBOOT_BASE_IMAGE_VERSION) {
package/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const REBOOT_VERSION = "0.22.0";
1
+ export declare const REBOOT_VERSION = "0.23.0";
package/version.js CHANGED
@@ -1 +1 @@
1
- export const REBOOT_VERSION = "0.22.0";
1
+ export const REBOOT_VERSION = "0.23.0";