Commit 4fcecf4
authored
fix(jsonata): lower default maxDepth to prevent Windows worker crash (#79)
* fix(jsonata): prevent Windows worker crash on StackOverflowError in JSONata evaluation
Root cause: Jsonata$Frame.lookup() traverses the frame parent chain recursively.
With the previous default maxDepth=1000, a recursive JSONata function can create
a 1000-deep frame chain, causing Frame.lookup() to recurse 1000 levels. Windows
JVM default thread stack (~256 KB) overflows before the ~512 KB Linux default does.
Reactor's throwIfFatal re-throws the Error, and ThreadUncaughtExceptionHandler
shuts down the entire worker process.
Three changes:
1. Catch StackOverflowError in evaluateExpression() and throw RuntimeException
so the task fails gracefully instead of crashing the worker.
2. Re-parse the expression after catching to get a clean Jsonata instance.
The Jsonata class has mutable fields (errors, environment) written during
evaluate(); leaving a partially-modified instance would cause all subsequent
evaluations on the same task instance (e.g. TransformItems batches) to fail
immediately on the errors-list check at evaluate() entry.
3. Lower default maxDepth from 1000 to 200. This makes JSONata's own JException
depth guard fire before the JVM stack overflows on Windows, while still
supporting non-trivial recursive expressions. Users with proven deep-recursion
needs can raise it explicitly in their flow YAML.
* refactor(jsonata): drop StackOverflowError catch, rely on JException depth guard
Catching StackOverflowError (a VirtualMachineError) is unsafe: the JVM
gives no recovery guarantee, and allocating inside the handler (re-parsing
the JSONata AST) can trigger further failures on a barely-unwound stack.
The Dashjoin JSONata engine already exposes a deterministic depth guard via
Frame.setRuntimeBounds(timeoutMillis, maxDepth). With maxDepth=200 (lowered
in the prior commit), the engine throws a clean JException before the Windows
256 KB thread stack overflows — making the StackOverflowError catch both
unsafe and unnecessary.
Remove the catch block and the parsedExpressionSource field that was only
needed to re-parse inside that handler.1 parent c6a2b00 commit 4fcecf4
2 files changed
Lines changed: 5 additions & 2 deletions
File tree
- plugin-transform-json/src/main/java/io/kestra/plugin/transform/jsonata
Lines changed: 4 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
15 | | - | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
16 | 19 | | |
17 | 20 | | |
18 | 21 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| |||
0 commit comments