{"record":{"id":"69efd28121a4b07e","repo":"karatelabs/karate","slug":"interrupted","errorCode":null,"errorMessage":"<interrupted>","messagePattern":"<interrupted>","errorType":"exception","errorClass":"io.karatelabs.js.EngineInterruptedException","httpStatus":null,"severity":"error","filePath":"karate-js/src/main/java/io/karatelabs/js/JsGenerator.java","lineNumber":93,"sourceCode":"                throw JsErrorException.typeError(\"Generator is already running\");\n            }\n            activation.retire(); // NOT_STARTED: no body code runs\n            ctx.stopAndThrow(value);\n            return Terms.UNDEFINED;\n        }\n        return drive(ctx, ResumeKind.THROW, value);\n    }\n\n    private Object drive(CoreContext ctx, ResumeKind kind, Object value) {\n        StepOutcome outcome = activation.step(kind, value);\n        return switch (outcome.kind) {\n            case YIELDED -> result(outcome.value, false);\n            case RETURNED -> result(outcome.value, true);\n            case THREW -> {\n                ctx.stopAndThrow(outcome.value);\n                yield Terms.UNDEFINED;\n            }\n            case HOST_CANCELLED -> throw new EngineInterruptedException();\n        };\n    }\n\n}\n","sourceCodeStart":75,"sourceCodeEnd":98,"githubUrl":"https://github.com/karatelabs/karate/blob/a22eb90246d958d15a47bf436693d0121ad2812d/karate-js/src/main/java/io/karatelabs/js/JsGenerator.java#L75-L98","documentation":"JsGenerator.drive throws EngineInterruptedException (message \"<interrupted>\") when a generator resumes while the engine has been host-cancelled (HOST_CANCELLED outcome). The library converts a cooperative cancellation signal into this engine exception so generator frames unwind cleanly instead of running to completion.","triggerScenarios":"The host (e.g. Karate runtime, timeout watchdog, or user abort) cancels the engine context while a generator is mid-yield; next(), return(), or throw() on the generator then sees HOST_CANCELLED.","commonSituations":"Scenario/step timeouts in Karate cancelling long-running JS generators; test shutdown while an async generator is suspended; explicit engine cancellation API invoked from Java host code.","solutions":["Treat it as cancellation, not a bug: catch EngineInterruptedException and unwind without retrying.","Check why the host cancelled (step timeout, abort call) and raise the timeout or shorten the generator work.","Ensure blocking work inside generators is cancellable/segmented so cancellation lands promptly.","If cancellation is unintended, audit host code paths that call engine stop/cancel APIs."],"exampleFix":"// before\nvar v = gen.next(); // may throw <interrupted> on host cancel\n// after\ntry { var v = gen.next(); } catch (e) { if (isInterrupted(e)) return; throw e; }","handlingStrategy":"try-catch","validationCode":"if (engine.isCancelled()) return; // check before resuming the generator","typeGuard":"boolean isCancellation(Throwable t) { return t instanceof EngineInterruptedException || (t.getCause() instanceof EngineInterruptedException); }","tryCatchPattern":"try { return gen.next(); } catch (EngineInterruptedException e) { cleanup(); return null; }","preventionTips":["Design generators to be cancellable: no indefinite blocking inside them.","Set generous-but-bounded step timeouts so cancellation is expected behavior.","Never retry after EngineInterruptedException — the host wanted to stop.","Log cancellation distinctly from failures for cleaner diagnostics."],"tags":["javascript","generator","cancellation","interrupted"],"backgroundTag":"thread-interrupted","analyzedSha":"a22eb90246d958d15a47bf436693d0121ad2812d","analyzedAt":"2026-09-12T09:01:00.220Z","contentChangedAt":"2026-09-12T09:01:00.220Z","schemaVersion":2},"datasetVersion":"2026-09-16T19:17:19.609Z"}