@oneuptime/common 12.0.11 → 12.0.12

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.
@@ -0,0 +1,121 @@
1
+ import JavaScriptCode from "../../../../../Server/Types/Workflow/Components/JavaScript";
2
+ import IfElse from "../../../../../Server/Types/Workflow/Components/Conditions/IfElse";
3
+ import {
4
+ RunOptions,
5
+ RunReturnType,
6
+ } from "../../../../../Server/Types/Workflow/ComponentCode";
7
+ import VMUtil from "../../../../../Server/Utils/VM/VMAPI";
8
+ import ReturnResult from "../../../../../Types/IsolatedVM/ReturnResult";
9
+ import Exception from "../../../../../Types/Exception/Exception";
10
+ import ObjectID from "../../../../../Types/ObjectID";
11
+ import { describe, expect, test, afterEach } from "@jest/globals";
12
+
13
+ interface OptionsFixture {
14
+ options: RunOptions;
15
+ log: jest.Mock;
16
+ onError: jest.Mock;
17
+ }
18
+
19
+ function makeOptions(): OptionsFixture {
20
+ const log: jest.Mock = jest.fn();
21
+ const onError: jest.Mock = jest.fn((exception: Exception): Exception => {
22
+ return exception;
23
+ });
24
+
25
+ return {
26
+ log,
27
+ onError,
28
+ options: {
29
+ log: log as RunOptions["log"],
30
+ workflowLogId: ObjectID.generate(),
31
+ workflowId: ObjectID.generate(),
32
+ projectId: ObjectID.generate(),
33
+ onError: onError as RunOptions["onError"],
34
+ executeWorkflow: async (): Promise<void> => {},
35
+ } as RunOptions,
36
+ };
37
+ }
38
+
39
+ afterEach(() => {
40
+ jest.restoreAllMocks();
41
+ });
42
+
43
+ describe("Custom JavaScript component scriptError routing", () => {
44
+ test("routes to the error port when the sandbox resolves with scriptError", async () => {
45
+ const sandboxResult: ReturnResult = {
46
+ returnValue: undefined,
47
+ logMessages: ["before failure"],
48
+ capturedMetrics: [],
49
+ scriptError: new Error("script exploded"),
50
+ };
51
+ jest.spyOn(VMUtil, "runCodeInSandbox").mockResolvedValue(sandboxResult);
52
+
53
+ const { options, log }: OptionsFixture = makeOptions();
54
+ const result: RunReturnType = await new JavaScriptCode().run(
55
+ { code: "throw new Error('script exploded');" },
56
+ options,
57
+ );
58
+
59
+ expect(result.executePort?.id).toBe("error");
60
+ expect(log).toHaveBeenCalledWith("before failure");
61
+ expect(log).toHaveBeenCalledWith("Error running script");
62
+ expect(log).toHaveBeenCalledWith("script exploded");
63
+ });
64
+
65
+ test("routes to the success port with the return value on success", async () => {
66
+ const sandboxResult: ReturnResult = {
67
+ returnValue: { answer: 42 },
68
+ logMessages: [],
69
+ capturedMetrics: [],
70
+ };
71
+ jest.spyOn(VMUtil, "runCodeInSandbox").mockResolvedValue(sandboxResult);
72
+
73
+ const { options }: OptionsFixture = makeOptions();
74
+ const result: RunReturnType = await new JavaScriptCode().run(
75
+ { code: "return { answer: 42 };" },
76
+ options,
77
+ );
78
+
79
+ expect(result.executePort?.id).toBe("success");
80
+ expect(result.returnValues).toEqual({ returnValue: { answer: 42 } });
81
+ });
82
+ });
83
+
84
+ describe("If/Else component scriptError handling", () => {
85
+ test("fails the run instead of silently taking a branch when the expression errors", async () => {
86
+ const sandboxResult: ReturnResult = {
87
+ returnValue: undefined,
88
+ logMessages: [],
89
+ capturedMetrics: [],
90
+ scriptError: new Error("expression exploded"),
91
+ };
92
+ jest.spyOn(VMUtil, "runCodeInSandbox").mockResolvedValue(sandboxResult);
93
+
94
+ const { options, onError }: OptionsFixture = makeOptions();
95
+
96
+ await expect(
97
+ new IfElse().run(
98
+ { "input-1": "a", "input-2": "b", operator: "==" },
99
+ options,
100
+ ),
101
+ ).rejects.toThrow("expression exploded");
102
+ expect(onError).toHaveBeenCalled();
103
+ });
104
+
105
+ test("takes the Yes branch when the expression evaluates truthy", async () => {
106
+ const sandboxResult: ReturnResult = {
107
+ returnValue: true,
108
+ logMessages: [],
109
+ capturedMetrics: [],
110
+ };
111
+ jest.spyOn(VMUtil, "runCodeInSandbox").mockResolvedValue(sandboxResult);
112
+
113
+ const { options }: OptionsFixture = makeOptions();
114
+ const result: RunReturnType = await new IfElse().run(
115
+ { "input-1": "a", "input-2": "a", operator: "==" },
116
+ options,
117
+ );
118
+
119
+ expect(result.executePort?.id).toBe("yes");
120
+ });
121
+ });
@@ -0,0 +1,92 @@
1
+ import MonitorCriteriaEvaluator from "../../../../Server/Utils/Monitor/MonitorCriteriaEvaluator";
2
+ import VMUtil from "../../../../Server/Utils/VM/VMAPI";
3
+ import Monitor from "../../../../Models/DatabaseModels/Monitor";
4
+ import MonitorStep from "../../../../Types/Monitor/MonitorStep";
5
+ import {
6
+ CheckOn,
7
+ CriteriaFilter,
8
+ } from "../../../../Types/Monitor/CriteriaFilter";
9
+ import MonitorType from "../../../../Types/Monitor/MonitorType";
10
+ import ReturnResult from "../../../../Types/IsolatedVM/ReturnResult";
11
+ import ObjectID from "../../../../Types/ObjectID";
12
+ import { describe, expect, test, afterEach } from "@jest/globals";
13
+
14
+ type EvaluatorPrivate = {
15
+ isMonitorInstanceCriteriaFilterMet: (input: {
16
+ dataToProcess: unknown;
17
+ monitorStep: MonitorStep;
18
+ monitor: Monitor;
19
+ probeApiIngestResponse: unknown;
20
+ criteriaInstance: unknown;
21
+ criteriaFilter: CriteriaFilter;
22
+ }) => Promise<string | null>;
23
+ };
24
+
25
+ const Evaluator: EvaluatorPrivate =
26
+ MonitorCriteriaEvaluator as unknown as EvaluatorPrivate;
27
+
28
+ function makeInput(): Parameters<
29
+ EvaluatorPrivate["isMonitorInstanceCriteriaFilterMet"]
30
+ >[0] {
31
+ const monitor: Monitor = new Monitor();
32
+ monitor.projectId = ObjectID.generate();
33
+ monitor.monitorType = MonitorType.Ping;
34
+
35
+ return {
36
+ dataToProcess: { isOnline: true },
37
+ monitorStep: new MonitorStep(),
38
+ monitor,
39
+ probeApiIngestResponse: {},
40
+ criteriaInstance: {},
41
+ criteriaFilter: {
42
+ checkOn: CheckOn.JavaScriptExpression,
43
+ value: "1 === 1",
44
+ } as CriteriaFilter,
45
+ };
46
+ }
47
+
48
+ afterEach(() => {
49
+ jest.restoreAllMocks();
50
+ });
51
+
52
+ describe("MonitorCriteriaEvaluator JavaScript expression criteria", () => {
53
+ test("treats a sandbox scriptError as criteria not met", async () => {
54
+ const sandboxResult: ReturnResult = {
55
+ returnValue: undefined,
56
+ logMessages: [],
57
+ capturedMetrics: [],
58
+ scriptError: new Error("expression exploded"),
59
+ };
60
+ jest.spyOn(VMUtil, "runCodeInSandbox").mockResolvedValue(sandboxResult);
61
+
62
+ const result: string | null =
63
+ await Evaluator.isMonitorInstanceCriteriaFilterMet(makeInput());
64
+
65
+ expect(result).toBeNull();
66
+ });
67
+
68
+ test("reports the criteria as met when the expression evaluates truthy", async () => {
69
+ const sandboxResult: ReturnResult = {
70
+ returnValue: true,
71
+ logMessages: [],
72
+ capturedMetrics: [],
73
+ };
74
+ jest.spyOn(VMUtil, "runCodeInSandbox").mockResolvedValue(sandboxResult);
75
+
76
+ const result: string | null =
77
+ await Evaluator.isMonitorInstanceCriteriaFilterMet(makeInput());
78
+
79
+ expect(result).toContain("evaluated to true");
80
+ });
81
+
82
+ test("treats a sandbox rejection as criteria not met", async () => {
83
+ jest
84
+ .spyOn(VMUtil, "runCodeInSandbox")
85
+ .mockRejectedValue(new Error("isolate crashed"));
86
+
87
+ const result: string | null =
88
+ await Evaluator.isMonitorInstanceCriteriaFilterMet(makeInput());
89
+
90
+ expect(result).toBeNull();
91
+ });
92
+ });
@@ -0,0 +1,385 @@
1
+ import VMRunner from "../../../../Server/Utils/VM/VMRunner";
2
+ import ReturnResult from "../../../../Types/IsolatedVM/ReturnResult";
3
+ import { JSONObject } from "../../../../Types/JSON";
4
+ import { describe, expect, jest, test } from "@jest/globals";
5
+ import axios from "axios";
6
+
7
+ jest.setTimeout(60000);
8
+
9
+ async function runInSandbox(data: {
10
+ code: string;
11
+ args?: JSONObject | undefined;
12
+ timeout?: number | undefined;
13
+ }): Promise<ReturnResult> {
14
+ return VMRunner.runCodeInSandbox({
15
+ code: data.code,
16
+ options: {
17
+ args: data.args,
18
+ timeout: data.timeout || 5000,
19
+ },
20
+ });
21
+ }
22
+
23
+ describe("VMRunner isolated-vm boundary", () => {
24
+ test("does not expose the legacy Node vm runner", () => {
25
+ const runnerApi: Record<string, unknown> = VMRunner as unknown as Record<
26
+ string,
27
+ unknown
28
+ >;
29
+
30
+ expect(runnerApi["runCodeInNodeVM"]).toBeUndefined();
31
+ });
32
+
33
+ test("does not expose Reference methods or temporary host globals", async () => {
34
+ const result: ReturnResult = await runInSandbox({
35
+ code: `
36
+ const privateNames = [
37
+ '_log',
38
+ '_captureMetric',
39
+ '_args',
40
+ '_axiosRef',
41
+ '_cryptoRef',
42
+ '_sleepRef',
43
+ '__oneuptimeHostLogCallback',
44
+ '__oneuptimeHostMetricCallback',
45
+ '__oneuptimeCopiedArgs',
46
+ '__oneuptimeHostAxiosCallback',
47
+ '__oneuptimeHostAxiosStartCallback',
48
+ '__oneuptimeHostAxiosPollCallback',
49
+ '__oneuptimeHostCryptoCallback',
50
+ '__oneuptimeHostSleepCallback',
51
+ '__oneuptimeHostSleepStartCallback',
52
+ '__oneuptimeHostSleepPollCallback',
53
+ ];
54
+ const referenceMethods = [
55
+ 'applySync',
56
+ 'applySyncPromise',
57
+ 'copy',
58
+ 'copySync',
59
+ 'deref',
60
+ 'derefInto',
61
+ 'getSync',
62
+ 'release',
63
+ 'setSync',
64
+ ];
65
+ const publicValues = [
66
+ console,
67
+ console.log,
68
+ oneuptime,
69
+ oneuptime.captureMetric,
70
+ args,
71
+ axios,
72
+ axios.get,
73
+ crypto,
74
+ crypto.randomUUID,
75
+ setTimeout,
76
+ sleep,
77
+ ];
78
+
79
+ return {
80
+ privateNamesPresent: privateNames.filter(name => name in globalThis),
81
+ valuesWithReferenceMethods: publicValues.map((value, index) => ({
82
+ index,
83
+ methods: referenceMethods.filter(method => {
84
+ try { return typeof value[method] !== 'undefined'; }
85
+ catch (_) { return true; }
86
+ }),
87
+ })).filter(entry => entry.methods.length > 0),
88
+ };
89
+ `,
90
+ });
91
+
92
+ expect(result.scriptError).toBeUndefined();
93
+ expect(result.returnValue).toEqual({
94
+ privateNamesPresent: [],
95
+ valuesWithReferenceMethods: [],
96
+ });
97
+ });
98
+
99
+ test("keeps every public function constructor in the isolate realm", async () => {
100
+ const result: ReturnResult = await runInSandbox({
101
+ code: `
102
+ const functions = [
103
+ console.log,
104
+ oneuptime.captureMetric,
105
+ axios,
106
+ axios.get,
107
+ crypto.randomUUID,
108
+ setTimeout,
109
+ sleep,
110
+ http.Agent,
111
+ https.Agent,
112
+ ];
113
+
114
+ return {
115
+ directFunction: Function('return typeof process')(),
116
+ constructors: functions.map(fn =>
117
+ fn.constructor.constructor('return typeof process')()
118
+ ),
119
+ };
120
+ `,
121
+ });
122
+
123
+ expect(result.scriptError).toBeUndefined();
124
+ expect(result.returnValue).toEqual({
125
+ directFunction: "undefined",
126
+ constructors: Array(9).fill("undefined"),
127
+ });
128
+ });
129
+
130
+ test("keeps promises returned by async shims in the isolate realm", async () => {
131
+ const result: ReturnResult = await runInSandbox({
132
+ code: `
133
+ const sleepPromise = sleep(0);
134
+ const axiosPromise = axios.get('http://127.0.0.1:8080/');
135
+ const promiseRealms = [sleepPromise, axiosPromise].map(promise =>
136
+ promise.constructor.constructor('return typeof process')()
137
+ );
138
+
139
+ await sleepPromise;
140
+ try { await axiosPromise; } catch (_) {}
141
+ return promiseRealms;
142
+ `,
143
+ });
144
+
145
+ expect(result.scriptError).toBeUndefined();
146
+ expect(result.returnValue).toEqual(["undefined", "undefined"]);
147
+ });
148
+
149
+ test("deep-copies args into the isolate realm", async () => {
150
+ const args: JSONObject = {
151
+ nested: {
152
+ value: "host value",
153
+ },
154
+ items: [1, 2, 3],
155
+ };
156
+
157
+ const result: ReturnResult = await runInSandbox({
158
+ args,
159
+ code: `
160
+ args.nested.value = 'isolate value';
161
+ args.items.push(4);
162
+
163
+ return {
164
+ nestedValue: args.nested.value,
165
+ itemCount: args.items.length,
166
+ objectPrototypeIsLocal: Object.getPrototypeOf(args) === Object.prototype,
167
+ constructorRealm: args.constructor.constructor('return typeof process')(),
168
+ };
169
+ `,
170
+ });
171
+
172
+ expect(result.scriptError).toBeUndefined();
173
+ expect(result.returnValue).toEqual({
174
+ nestedValue: "isolate value",
175
+ itemCount: 4,
176
+ objectPrototypeIsLocal: true,
177
+ constructorRealm: "undefined",
178
+ });
179
+ expect(args).toEqual({
180
+ nested: {
181
+ value: "host value",
182
+ },
183
+ items: [1, 2, 3],
184
+ });
185
+ });
186
+
187
+ test("retains logs and metrics when user code throws", async () => {
188
+ const result: ReturnResult = await runInSandbox({
189
+ code: `
190
+ console.log('before throw', { safe: true });
191
+ oneuptime.captureMetric('sandbox_metric', 42, { region: 'test' });
192
+ const error = new Error('expected isolate failure');
193
+ error.untrustedProperty = 'must not cross';
194
+ throw error;
195
+ `,
196
+ });
197
+
198
+ expect(result.returnValue).toBeUndefined();
199
+ expect(result.logMessages).toEqual(['before throw {"safe":true}']);
200
+ expect(result.capturedMetrics).toEqual([
201
+ {
202
+ name: "sandbox_metric",
203
+ value: 42,
204
+ attributes: { region: "test" },
205
+ },
206
+ ]);
207
+ expect(result.scriptError).toBeInstanceOf(Error);
208
+ expect(result.scriptError?.message).toBe("expected isolate failure");
209
+ expect(
210
+ (result.scriptError as Error & { untrustedProperty?: string })
211
+ .untrustedProperty,
212
+ ).toBeUndefined();
213
+ expect(result.scriptError?.stack).not.toContain("untrustedProperty");
214
+ });
215
+
216
+ test("retains logs and metrics when user code times out", async () => {
217
+ const result: ReturnResult = await runInSandbox({
218
+ timeout: 50,
219
+ code: `
220
+ console.log('before timeout');
221
+ oneuptime.captureMetric('timeout_metric', 7);
222
+ while (true) {}
223
+ `,
224
+ });
225
+
226
+ expect(result.returnValue).toBeUndefined();
227
+ expect(result.logMessages).toEqual(["before timeout"]);
228
+ expect(result.capturedMetrics).toEqual([
229
+ {
230
+ name: "timeout_metric",
231
+ value: 7,
232
+ },
233
+ ]);
234
+ expect(result.scriptError?.message).toMatch(/timed out/i);
235
+ });
236
+
237
+ test("bounds log count and aggregate UTF-8 bytes", async () => {
238
+ const countResult: ReturnResult = await runInSandbox({
239
+ code: `
240
+ for (let index = 0; index < 1100; index++) {
241
+ console.log('entry-' + index);
242
+ }
243
+ return 'done';
244
+ `,
245
+ });
246
+
247
+ expect(countResult.scriptError).toBeUndefined();
248
+ expect(countResult.returnValue).toBe("done");
249
+ expect(countResult.logMessages).toHaveLength(1000);
250
+
251
+ const byteResult: ReturnResult = await runInSandbox({
252
+ code: `
253
+ const message = '\u00e9'.repeat(70000);
254
+ for (let index = 0; index < 10; index++) {
255
+ console.log(message);
256
+ }
257
+ return 'done';
258
+ `,
259
+ });
260
+ const totalBytes: number = byteResult.logMessages.reduce(
261
+ (bytes: number, message: string): number => {
262
+ return bytes + Buffer.byteLength(message, "utf8");
263
+ },
264
+ 0,
265
+ );
266
+
267
+ expect(byteResult.scriptError).toBeUndefined();
268
+ expect(totalBytes).toBeLessThanOrEqual(1_000_000);
269
+ expect(byteResult.logMessages).toHaveLength(7);
270
+ });
271
+
272
+ test("preserves timer behavior and clears pending host timers", async () => {
273
+ jest.spyOn(global, "clearTimeout");
274
+
275
+ try {
276
+ const result: ReturnResult = await runInSandbox({
277
+ timeout: 250,
278
+ code: `
279
+ let cancelledTimerFired = false;
280
+ const cancelledTimer = setTimeout(() => {
281
+ cancelledTimerFired = true;
282
+ }, 5);
283
+ clearTimeout(cancelledTimer);
284
+
285
+ const startedAt = Date.now();
286
+ await new Promise(resolve => setTimeout(resolve, 10));
287
+ const elapsed = Date.now() - startedAt;
288
+
289
+ setTimeout(() => console.log('late timer'), 60000);
290
+ await sleep(5);
291
+
292
+ return {
293
+ cancelledTimerFired,
294
+ elapsed,
295
+ };
296
+ `,
297
+ });
298
+
299
+ expect(result.scriptError).toBeUndefined();
300
+ expect(result.returnValue.cancelledTimerFired).toBe(false);
301
+ expect(result.returnValue.elapsed).toBeGreaterThanOrEqual(5);
302
+ expect(result.logMessages).not.toContain("late timer");
303
+ expect(
304
+ jest.mocked(global.clearTimeout).mock.calls.length,
305
+ ).toBeGreaterThanOrEqual(2);
306
+ } finally {
307
+ jest.restoreAllMocks();
308
+ }
309
+ });
310
+
311
+ test("copies a fulfilled axios response back into the isolate", async () => {
312
+ jest.spyOn(axios, "get").mockResolvedValue({
313
+ status: 200,
314
+ headers: { "x-test": "copied" },
315
+ data: { ok: true },
316
+ } as never);
317
+
318
+ try {
319
+ const result: ReturnResult = await runInSandbox({
320
+ code: `
321
+ const response = await axios.get('https://8.8.8.8/health');
322
+ return {
323
+ status: response.status,
324
+ header: response.headers['x-test'],
325
+ data: response.data,
326
+ promiseRealm: axios.get('https://8.8.8.8/second')
327
+ .constructor.constructor('return typeof process')(),
328
+ };
329
+ `,
330
+ });
331
+
332
+ expect(result.scriptError).toBeUndefined();
333
+ expect(result.returnValue).toEqual({
334
+ status: 200,
335
+ header: "copied",
336
+ data: { ok: true },
337
+ promiseRealm: "undefined",
338
+ });
339
+ expect(axios.get).toHaveBeenCalledWith(
340
+ "https://8.8.8.8/health",
341
+ expect.objectContaining({
342
+ maxRedirects: 0,
343
+ signal: expect.any(AbortSignal),
344
+ }),
345
+ );
346
+ } finally {
347
+ jest.restoreAllMocks();
348
+ }
349
+ });
350
+
351
+ test("keeps the documented crypto and Agent shims compatible", async () => {
352
+ const result: ReturnResult = await runInSandbox({
353
+ code: `
354
+ const httpAgent = new http.Agent({ keepAlive: true });
355
+ const httpsAgent = new https.Agent({ rejectUnauthorized: false });
356
+
357
+ return {
358
+ hash: crypto.createHash('sha256').update('oneuptime').digest('hex'),
359
+ uuidLooksValid: /^[0-9a-f-]{36}$/.test(crypto.randomUUID()),
360
+ randomIntInRange: (() => {
361
+ const value = crypto.randomInt(2, 5);
362
+ return value >= 2 && value < 5;
363
+ })(),
364
+ httpAgent,
365
+ httpsAgent,
366
+ };
367
+ `,
368
+ });
369
+
370
+ expect(result.scriptError).toBeUndefined();
371
+ expect(result.returnValue).toEqual({
372
+ hash: "35a18a92a1ae8387b173763364c1497950fa0bfe2589e545c0bf1f4d0f01f94e",
373
+ uuidLooksValid: true,
374
+ randomIntInRange: true,
375
+ httpAgent: {
376
+ __agentType: "__http_agent__",
377
+ options: { keepAlive: true },
378
+ },
379
+ httpsAgent: {
380
+ __agentType: "__https_agent__",
381
+ options: { rejectUnauthorized: false },
382
+ },
383
+ });
384
+ });
385
+ });
@@ -33,6 +33,9 @@ async function runInSandbox(code: string): Promise<ReturnResult> {
33
33
  async function errorFromSandbox(code: string): Promise<string> {
34
34
  try {
35
35
  const result: ReturnResult = await runInSandbox(code);
36
+ if (result.scriptError) {
37
+ return result.scriptError.message;
38
+ }
36
39
  return JSON.stringify(result.returnValue ?? result.logMessages ?? "");
37
40
  } catch (err) {
38
41
  return (err as Error).message || String(err);
@@ -1,5 +1,17 @@
1
1
  import CapturedMetric from "./CapturedMetric";
2
- import { JSONObject } from "../../JSON";
2
+
3
+ export interface CustomCodeMonitorResultObject {
4
+ [key: string]: CustomCodeMonitorResult;
5
+ }
6
+
7
+ /** JSON-safe data returned from a custom or synthetic monitor script. */
8
+ export type CustomCodeMonitorResult =
9
+ | string
10
+ | number
11
+ | boolean
12
+ | null
13
+ | CustomCodeMonitorResultObject
14
+ | Array<CustomCodeMonitorResult>;
3
15
 
4
16
  export interface RetryAttempt {
5
17
  attemptNumber: number;
@@ -8,7 +20,7 @@ export interface RetryAttempt {
8
20
  }
9
21
 
10
22
  export default interface CustomCodeMonitorResponse {
11
- result: string | number | boolean | JSONObject | undefined;
23
+ result: CustomCodeMonitorResult | undefined;
12
24
  scriptError?: string | undefined;
13
25
  logMessages: string[];
14
26
  capturedMetrics: CapturedMetric[];
@@ -121,6 +121,14 @@ export default class IfElse extends ComponentCode {
121
121
  logMessages.forEach((msg) => {
122
122
  options.log(msg);
123
123
  });
124
+ /*
125
+ * runCodeInSandbox resolves with `scriptError` when the expression
126
+ * threw or timed out — it no longer rejects. Fail the run instead of
127
+ * silently taking the "No" branch.
128
+ */
129
+ if (returnResult.scriptError) {
130
+ throw returnResult.scriptError;
131
+ }
124
132
  if (returnResult.returnValue) {
125
133
  return {
126
134
  returnValues: {},
@@ -1 +1 @@
1
- {"version":3,"file":"IfElse.js","sourceRoot":"","sources":["../../../../../../../Server/Types/Workflow/Components/Conditions/IfElse.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IfElse.js","sourceRoot":"","sources":["../../../../../../../Server/Types/Workflow/Components/Conditions/IfElse.ts"],"names":[],"mappings":"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"}
@@ -61,6 +61,14 @@ export default class JavaScriptCode extends ComponentCode {
61
61
  logMessages.forEach((msg) => {
62
62
  options.log(msg);
63
63
  });
64
+ /*
65
+ * runCodeInSandbox resolves with `scriptError` when the user script
66
+ * threw or timed out — it no longer rejects. Route those runs to the
67
+ * error port, matching the pre-sandbox behavior.
68
+ */
69
+ if (returnResult.scriptError) {
70
+ throw returnResult.scriptError;
71
+ }
64
72
  const returnVal = returnResult.returnValue;
65
73
  return {
66
74
  returnValues: {