Errors
How GocciaScript reports errors to script authors, CLI users, and embedders.
Executive Summary
- Error types --
Error,TypeError,ReferenceError,RangeError,SyntaxError,URIError,AggregateError,SuppressedError, plus the uncatchable resource ceilingsTimeoutError(--timeout),InstructionLimitError(--max-instructions), andMemoryLimitError(--max-memory) --max-memoryrefuses in two ways -- both force a collection and re-test first, and they differ in what the guest can do about the answer. A charged allocation (string payload,ArrayBufferbacking store) throws a catchableRangeError; a gated growth point (array element storage, object property storage) ends the run with the uncatchableMemoryLimitError. Either way, two shapes no collection could help are refused straight away without walking the heap -- a request larger than the whole budget, and a repeat of one a forced collection has already refused. The same byte count can therefore be survivable on one path and fatal on the other -- see Garbage Collector § Gated growth points- Engine-integrity faults -- A fourth uncatchable class, and not an error type at all: a use-after-free, an invalid dereference, or a broken heap unwinds past every
catchto the host, because a script cannot meaningfully continue on top of one. See ADR 0109 - Parser errors -- Displayed with source context, a caret pointing to the exact column, and optional suggestion text (e.g., "Use 'let' or 'const' instead")
- Runtime errors -- Carry
name,message,stack, and optionalcause; catchable withtry/catch/finally - Sandbox filesystem errors -- Use real
Errorobjects with Node-shapedcode,errno,path,syscall, and optionaldestmetadata - Module loading errors -- Script-visible failures name only the specifier as written; the expanded host path reaches hosts through the typed exception and human-readable CLI output, never through
error.message(the JSON envelope'serror.fileNameremains a host-side path, as it is for every error type) - JSON output --
--output=jsonwraps every execution result in a structured envelope withok,error.type,error.message,error.line, anderror.column.--output=compact-jsonproduces the same envelope without thebuild,memory,stdout, orstderrfields, leaving only the normalizedoutputarray and structurederrorfor console output. The samecompact-jsonvalue is recognised byGocciaTestRunner(via--output) andGocciaBenchmarkRunner(via--format). Error.cause-- All error constructors accept an options bag with acauseproperty for error chaining (ES2022+)
Error Types
GocciaScript supports the standard ECMAScript error constructors plus the CLI-only resource-ceiling types below. All JavaScript-visible error types inherit from Error and work with instanceof. TimeoutError, InstructionLimitError, and MemoryLimitError are CLI-only and not exposed as JavaScript constructors.
| Type | Thrown when | MDN |
|---|---|---|
Error | Generic errors; base class for all error types | Error |
TypeError | Property access on null/undefined, calling a non-function, reassigning const, calling a constructor without new | TypeError |
ReferenceError | Accessing an undeclared variable, using a variable before initialization (TDZ) | ReferenceError |
RangeError | Invalid array length, negative ArrayBuffer size, out-of-range numeric conversions, call stack depth exceeded (--stack-size) | RangeError |
SyntaxError | Invalid syntax detected by the parser or lexer; also throwable at runtime via new SyntaxError(...) | SyntaxError |
URIError | Malformed URI passed to encodeURI, decodeURI, encodeURIComponent, or decodeURIComponent | URIError |
AggregateError | Multiple errors wrapped together; used by Promise.any when all promises reject | AggregateError |
SuppressedError | Disposal error during explicit resource management (using/await using); wraps both the new and suppressed error | SuppressedError |
TimeoutError | Execution exceeded the --timeout limit (CLI only; not a JS-visible constructor) | -- |
InstructionLimitError | Execution exceeded the --max-instructions budget (CLI only; not a JS-visible constructor) | -- |
MemoryLimitError | A gated growth point -- array element storage or object property storage -- was refused by the --max-memory budget after a forced collection failed to make room. Charged allocations under the same budget throw a catchable RangeError instead (CLI only; not a JS-visible constructor) | -- |
The last three are resource ceilings rather than in-language errors. Script
try/catch cannot observe them in either execution mode: they unwind past
every handler to the host, because a ceiling the guest can catch is a ceiling
the guest can ignore in a loop. Allocation sites that charge the budget
against an owning value (string payloads, ArrayBuffer) still throw an
ordinary catchable RangeError, which is unchanged.
One more class of failure is uncatchable, for a stronger reason and without
appearing in the table at all: an engine-integrity fault -- a virtual call
through a collected value, an invalid dereference, a heap whose bookkeeping has
been destroyed. These are engine bugs rather than anything the script did, and
unlike a refused allocation they have no defined continuation, so they unwind
past every catch to the host instead of becoming an Error object. A refused
allocation is deliberately not one of them: it leaves the heap intact, so
catching it and retrying with less remains valid. ADR
0109 records the decision;
source/units/Goccia.EngineFault.pas is the authoritative list of the classes.
Inheritance
All error types follow the standard prototype chain:
const e = new TypeError("bad type");e instanceof TypeError; // truee instanceof Error; // truee instanceof RangeError; // false
Errors thrown internally by the engine (e.g., property access on null) use the same prototype chain as user-constructed errors, so instanceof checks work consistently in catch blocks.
Error.isError
GocciaScript implements the ES2026 Error.isError static method, which checks for the internal [[ErrorData]] slot:
Error.isError(new TypeError("x")); // trueError.isError({ message: "fake" }); // false — plain objects are not errors
Parser Error Display
When the parser encounters invalid syntax, it displays a detailed error with source context. The format includes the error name, message, file location, the offending source line, and a caret (^) pointing to the exact column:
SyntaxError: Expected ';' after expression--> script.js:3:121 | const x = 12 | const y = 23 | const z = 3 + +^4 | console.log(z);
Up to 2 lines of context are shown before and after the error line.
Suggestions
Some parser errors include a suggestion line that recommends an alternative. GocciaScript intentionally excludes certain JavaScript features and uses suggestions to guide users toward the supported alternatives:
SyntaxError: 'var' declarations are not supported in GocciaScriptSuggestion: Use 'let' or 'const' instead--> script.js:1:11 | var x = 42;^
Other features that produce suggestions include:
vardeclarations -- suggestsletorconstfunctiondeclarations and expressions -- suggests arrow functions==/!=(loose equality) -- suggests===/!==- Traditional
for(init; test; update)loops when--compat-traditional-for-loopis off -- suggestsfor...of, array methods, or the flag for...inloops when--compat-for-in-loopis off -- suggestsObject.keys()/Object.entries()withfor...of, or the flagwhile/do...whileloops when--compat-while-loopsis off -- suggestsfor...of, array methods, or the flag
See Language for the recommended profile, compatibility paths, and their rationale.
Runtime Error Display
When an uncaught runtime error reaches the top level, GocciaScript displays the error with the same source-context format used by parser errors. The stack trace from the error's stack property is used to locate the offending line in source:
TypeError: Cannot read properties of undefined (reading 'x')--> script.js:5:103 | const getX = (obj) => {4 | return obj.x;5 | return obj.nested.x;^6 | };7 | getX(undefined);
Stdin input uses <stdin> as the filename and retains full source context for error display. If source context is not available (e.g., errors originating inside native function callbacks without a JavaScript source location), GocciaScript falls back to displaying the stack trace string.
Error Properties
Every error object has the following properties:
| Property | Type | Description |
|---|---|---|
name | string | Error type name (e.g., "TypeError", "RangeError") |
message | string | Human-readable error description |
stack | string | Formatted stack trace (see Stack Traces) |
cause | any | Optional; present only when constructed with { cause } option (see Error.cause) |
AggregateError adds:
| Property | Type | Description |
|---|---|---|
errors | Array | The array of errors passed to the constructor |
SuppressedError adds:
| Property | Type | Description |
|---|---|---|
error | any | The error that triggered the suppression |
suppressed | any | The original error that was suppressed |
Sandbox filesystem errors
The Sandbox Runner's fs module converts virtual filesystem failures into
real JavaScript Error objects. Synchronous methods throw the error and
fs.promises methods reject with the same shape. Callback methods pass the
same error as their only callback argument, except fs.exists, which converts
filesystem failures to false.
In addition to the standard error properties, sandbox filesystem errors have:
| Property | Type | Description |
|---|---|---|
code | string | Portable error code such as "ENOENT" |
errno | number | Negative, target-appropriate libuv-style error number |
path | string | Original source path passed to the fs method |
syscall | string | Stable sandbox operation name, such as "readFile" or "rename" |
dest | string | Original destination path; present only for rename and copyFile |
The sandbox operation name is independent of the API form: for example,
readFileSync, fs.promises.readFile, and callback readFile failures all
report syscall === "readFile". This identifies the virtual operation rather
than claiming that the sandbox performed an operating-system call.
| Virtual filesystem failure | code | Message description |
|---|---|---|
| Invalid path | EINVAL | invalid argument |
| Path not found | ENOENT | no such file or directory |
| Path already exists | EEXIST | file already exists |
| Path component is not a directory | ENOTDIR | not a directory |
| File operation targets a directory | EISDIR | illegal operation on a directory |
| Directory is not empty | ENOTEMPTY | directory not empty |
| File or directory is busy | EBUSY | resource busy or locked |
| Sandbox byte quota exceeded | ENOSPC | no space left on device |
| Unexpected unclassified filesystem failure (internal fallback) | EIO | i/o error |
Messages follow Node's system-error wording:
ENOENT: no such file or directory, readFile '/missing.txt'ENOENT: no such file or directory, rename '/missing.txt' -> '/destination.txt'
code is the portable field to branch on. Numeric errno follows libuv's
target convention, so its value can differ between operating systems.
Module loading errors
When a static or dynamic import fails against the host filesystem, the
script-visible error message names only the specifier as the import statement
wrote it:
try {await import("./missing.js");} catch (error) {error.message; // 'Module not found: "./missing.js"'}
The expanded host filesystem address is deliberately absent. Script code — including untrusted guest code — must not be able to map the host directory layout by importing probe specifiers, so no module-loading failure message reaching a JavaScript error object contains an expanded path, an applied alias replacement, or the importing file's base directory. This covers the whole load path, not resolution alone:
| Failure | Script-visible message |
|---|---|
| Specifier does not resolve | Module not found: "./missing.js" |
import.source of a non-script module | Module source is not available for "./data.json" |
| JSON module fails to parse | Failed to parse JSON module "./data.json": <parse detail> |
See ADR 0108 — Specifier-only module resolution errors.
Hosts keep the resolution diagnostic on the human-readable output path. The
resolver raises the typed Pascal exception EModuleNotFound
(Goccia.ModuleResolver), whose read-only ResolvedCandidatePath property
carries the expanded candidate; the module loader forwards it on
TGocciaModuleResolutionError (Goccia.Modules.Resolver), and the CLI
reporters render it through FormatHostErrorDiagnostic as its own line:
RuntimeError: Module not found: "./missing.js"--> /home/user/project/entry.js:0:0Resolved to: /home/user/project/missing.js
--output=json and --output=compact-json do not carry it. The JSON
envelope's error object is the documented set of type, message, line,
column, and fileName, and its message is the same sanitized text script
sees. Embedders that need the candidate path should catch EModuleNotFound or
TGocciaModuleResolutionError directly rather than parse CLI JSON. The other
two message shapes above carry no structured host counterpart at all — the
expanded path survives only in the error's FileName field, which stays
host-side: the --> line of human-readable output and the envelope's
error.fileName, never error.message.
Two resolution messages are unaffected because they never carried a host path:
a bare specifier reports Cannot resolve bare module specifier "lodash". Imports must start with "./" or "../", and a runtime configured without a resolver
reports No module resolver configured and cannot resolve "./missing.js".
Sandbox modules are exempt. The Sandbox Runner resolves against a virtual
filesystem the guest already owns and can enumerate, so its resolution failures
keep the (resolved to "...") and (alias resolved to "...") detail — those
paths are guest namespace, not host namespace.
No content provider configured
An engine that was never given a module content provider refuses every module
load it is asked to retrieve. The refusal is a JavaScript error rather than an
RTL exception: import() rejects with it and source can catch it, and a static
import — which no try/catch in the importing module can wrap — surfaces it as
a JavaScript throw (TGocciaThrowValue) carrying the same error value.
Loading a module is resolution followed by retrieval, and only retrieval reaches
the provider. A specifier the resolver rejects fails first, and that is a
different failure carrying no code — with the default resolver, which resolves
against the host filesystem, import "./dep.js" where dep.js does not exist
fails there. import() rejects with a plain Error reading
Module not found: "./dep.js", and a static import raises
TGocciaRuntimeError out of the engine as a host-language exception. So an
embedder still has to guard its engine boundary. Resolution messages name only
the specifier as written (see above), matching the refusal below.
In addition to the standard error properties, the refusal carries:
| Property | Type | Description |
|---|---|---|
code | string | "ERR_MODULE_LOADING_UNSUPPORTED" |
try {await import("./dep.js"); // resolves, no provider installed} catch (error) {error instanceof Error; // trueerror.name; // "Error"error.code; // "ERR_MODULE_LOADING_UNSUPPORTED"error.message; // "Cannot load module: no module content provider is configured"error.path; // undefined — see below}
There is deliberately no path, and the message names no module address. The
only address available where the refusal is raised is the resolved one, which
the default resolver expands into an absolute host filesystem path, and an
engine with no provider is exactly the configuration an embedder runs untrusted
source in — an enumerable own property would carry that host detail into
JSON.stringify(error) and object spread. Nothing is lost: while no provider is
installed the refusal is unconditional for every module, so acting on it never
depends on which one was asked for. Contrast
sandbox filesystem errors, whose path is a
sandbox VFS address the guest itself named.
The error type is a plain Error rather than a TypeError. ECMA-262
HostLoadImportedModule requires a throw completion but mandates no type, and
for this case — an engine with no loader at all — V8, JavaScriptCore, and
SpiderMonkey all report a plain Error; TypeError is the convention for a
configured loader that tried and failed. Because the constructor cannot
separate the two, code is the field to branch on: a provider that is
configured and cannot produce a module reports its own failure and never
ERR_MODULE_LOADING_UNSUPPORTED. See
ADR 0106 for the full rationale, and
Embedding for how to install a
provider.
Stack Traces
The stack property contains a V8-style formatted string with the error header followed by at frames:
TypeError: Cannot read properties of nullat inner (script.js:2:10)at middle (script.js:5:3)at outer (script.js:8:3)
Each frame shows the function name (or <anonymous>), the file path, and the line and column number. Frames are listed from innermost (most recent) to outermost.
Error.cause
Most error constructors accept an options object with a cause property, following ES2022 Error Cause. The options argument position varies by constructor: second for Error, TypeError, RangeError, ReferenceError, SyntaxError, and URIError; third for AggregateError (new AggregateError(errors, message, options)); fourth for SuppressedError (new SuppressedError(error, suppressed, message, options)).
const original = new Error("disk full");const wrapped = new Error("save failed", { cause: original });wrapped.message; // "save failed"wrapped.cause.message; // "disk full"
Error cause chaining works across error types:
const root = new RangeError("out of bounds");const mid = new TypeError("invalid type", { cause: root });const top = new Error("operation failed", { cause: mid });top.cause.cause.message; // "out of bounds"
The cause property:
- Can be any value (string, number, object, another error,
null,undefined) - Is writable and configurable but not enumerable
- Is only present when the options object has a
causeproperty (not present by default) - Works with all error types:
Error,TypeError,RangeError,ReferenceError,SyntaxError,URIError,AggregateError, andSuppressedError
try / catch / finally
Error handling follows standard ECMAScript semantics. See Language for the full syntax reference.
Basic try/catch
try {const x = null;x.property; // throws TypeError} catch (e) {console.log(e.name); // "TypeError"console.log(e.message); // "Cannot read properties of null (reading 'property')"}
Optional catch binding
The catch parameter can be omitted (ES2019+):
try {riskyOperation();} catch {console.log("something went wrong");}
finally
The finally block always runs, whether or not an error was thrown:
try {return computeResult();} finally {cleanup(); // runs even when try returns}
Per the spec, if finally contains a return, throw, or break, it overrides the try/catch result.
Throwing any value
GocciaScript allows throwing any value, not just error objects:
try {throw "string error";} catch (e) {console.log(e); // "string error"}try {throw 42;} catch (e) {console.log(e); // 42}
Type-checking caught errors
Use instanceof to differentiate error types in a catch block:
try {someOperation();} catch (e) {if (e instanceof TypeError) {console.log("type error:", e.message);} else if (e instanceof RangeError) {console.log("range error:", e.message);} else {throw e; // rethrow unknown errors}}
SuppressedError and Explicit Resource Management
When using using or await using declarations for explicit resource management, if both the block body and a resource's [Symbol.dispose]() method throw, the runtime wraps both errors in a SuppressedError:
let caught;try {using resource = {[Symbol.dispose]() { throw new Error("disposal failed"); }};throw new Error("block failed");} catch (e) {caught = e;}caught instanceof SuppressedError; // truecaught.error.message; // "disposal failed"caught.suppressed.message; // "block failed"
If multiple disposals fail, errors are chained: each new disposal error wraps the previous SuppressedError as its suppressed property.
SuppressedError can also be constructed directly:
const err = new SuppressedError(new Error("new"), // errornew Error("old"), // suppressed"An error was suppressed" // message (optional));err.name; // "SuppressedError"err.error; // Error: newerr.suppressed; // Error: olderr.message; // "An error was suppressed"
JSON Output Format
When running with --output=json, GocciaScript wraps every execution result in a structured JSON envelope. This is useful for programmatic consumers and embedding scenarios.
The memory block has two different scopes:
memory.gcreports the GocciaScript GC's approximate managed-object accounting. It tracksTGCManagedObject.InstanceSize, not all memory held by strings, dynamic arrays, or the FreePascal runtime.allocatedDuringRunBytesis cumulative allocation churn during the measured run, so it can be much larger thanliveBytes.memory.heapreports coarse FreePascal process heap-manager counters fromGetHeapStatus. These are allocator diagnostics, not JavaScript heap size.deltaFreeBytesmay be negative when the process heap has less reusable free space at the end of the run.
For parallel runs, the top-level memory.gc block combines one measurement per worker thread plus the main thread. It does not sum per-file live snapshots, because each worker can process many files with the same thread-local GC. Per-file files[].memory is only populated by hosts that can measure a file independently.
Success
{"ok": true,"build": {"version": "0.1.0-dev","date": "2026-04-27","commit": "abc1234","os": "darwin","arch": "aarch64"},"stdout": "hello\n","stderr": "","output": ["hello"],"error": null,"timing": {"lex_ns": 500000,"parse_ns": 1200000,"compile_ns": 0,"exec_ns": 3100000,"total_ns": 4800000},"memory": {"gc": {"liveBytes": 2048,"startLiveBytes": 0,"endLiveBytes": 2048,"peakLiveBytes": 4096,"deltaLiveBytes": 2048,"allocatedDuringRunBytes": 4096,"limitBytes": 536870912,"startObjectCount": 0,"endObjectCount": 24,"collections": 0,"collectedObjects": 0},"heap": {"startAllocatedBytes": 16384,"endAllocatedBytes": 32768,"deltaAllocatedBytes": 16384,"startFreeBytes": 8192,"endFreeBytes": 4096,"deltaFreeBytes": -4096}},"workers": { "used": 1, "available": 1, "parallel": false },"files": [{"fileName": "script.js","ok": true,"stdout": "hello\n","stderr": "","output": ["hello"],"error": null,"timing": {"lex_ns": 500000,"parse_ns": 1200000,"compile_ns": 0,"exec_ns": 3100000,"total_ns": 4800000},"memory": { "gc": { "liveBytes": 2048 }, "heap": { "endAllocatedBytes": 32768 } },"result": 42}]}
Error
{"ok": false,"build": {"version": "0.1.0-dev","date": "2026-04-27","commit": "abc1234","os": "darwin","arch": "aarch64"},"stdout": "","stderr": "","output": [],"error": {"type": "TypeError","message": "Cannot read properties of null (reading 'x')","line": 5,"column": 10,"fileName": "script.js"},"timing": {"lex_ns": 500000,"parse_ns": 1200000,"compile_ns": 0,"exec_ns": 100000,"total_ns": 1800000},"memory": { "gc": { "liveBytes": 2048 }, "heap": { "endAllocatedBytes": 32768 } },"workers": { "used": 1, "available": 1, "parallel": false },"files": [{"fileName": "script.js","ok": false,"stdout": "","stderr": "","output": [],"error": {"type": "TypeError","message": "Cannot read properties of null (reading 'x')","line": 5,"column": 10,"fileName": "script.js"},"timing": {"lex_ns": 500000,"parse_ns": 1200000,"compile_ns": 0,"exec_ns": 100000,"total_ns": 1800000},"memory": { "gc": { "liveBytes": 2048 }, "heap": { "endAllocatedBytes": 32768 } },"result": null}]}
| Field | Type | Description |
|---|---|---|
ok | boolean | true for success, false for error |
build | object | Build identity, including version, date, commit, os, and arch |
stdout | string | Unformatted stdout-oriented console output; present even when empty |
stderr | string | Unformatted stderr-oriented console output; present even when empty |
output | string[] | Formatted console output split into lines |
error | object | null | First failed file's error details, or null when the run succeeds |
error.type | string | Error type name ("TypeError", "SyntaxError", "TimeoutError", "MemoryLimitError", etc.) |
error.message | string | Error message text |
error.line | number | null | Source line number (1-based), or null if unavailable |
error.column | number | null | Source column number (1-based), or null if unavailable |
error.fileName | string | null | Source file path, or null if unavailable |
timing | object | Cumulative phase-level timings in nanoseconds (*_ns) |
memory | object | null | GC and application heap measurements for the run |
memory.gc.liveBytes | number | GC-managed bytes live at the measurement endpoint. This is the report equivalent of Goccia.gc.bytesAllocated |
memory.gc.allocatedDuringRunBytes | number | Total GC-managed bytes allocated during the measured run, including allocations later collected |
memory.gc.peakLiveBytes | number | Highest live GC-managed byte count observed during the measurement |
memory.gc.limitBytes | number | Active GC byte ceiling from --max-memory or the auto-detected default |
memory.heap.deltaAllocatedBytes | number | Change in FreePascal heap-manager allocated bytes for the measured process/thread scope |
memory.heap.deltaFreeBytes | number | Change in FreePascal memory-manager free space. Negative values are valid and mean the process heap had less reusable free space at the end |
workers | object | Worker logistics: used worker count, available worker count, and whether the run was parallel |
files | object[] | Per-input results. Single-file runs use the same structure with one element |
files[].fileName | string | Input file path or <stdin> |
files[].result | any | The script completion value for that input. Serializes as null for both errors and JavaScript undefined; use files[].ok and files[].error to distinguish those cases. |
Compact JSON Output
--output=compact-json emits the same envelope as --output=json with the build, memory, stdout, and stderr fields omitted at both the top level and per-file. All console output is still available through the normalized output array (lines from console.log/info/debug and prefixed lines like Error: ... or Warning: ... from console.error/warn); script errors remain available through the structured error object. Use this format when you do not need build identity, memory measurements, or the raw stdout/stderr split — and want a smaller payload.
{"ok": true,"output": ["hello", "Error: oops"],"error": null,"timing": {"lex_ns": 500000,"parse_ns": 1200000,"compile_ns": 0,"exec_ns": 3100000,"total_ns": 4800000},"workers": { "used": 1, "available": 1, "parallel": false },"files": [{"fileName": "script.js","ok": true,"output": ["hello", "Error: oops"],"error": null,"timing": {"lex_ns": 500000,"parse_ns": 1200000,"compile_ns": 0,"exec_ns": 3100000,"total_ns": 4800000},"result": 42}]}
TimeoutError in JSON
When execution exceeds the --timeout limit, the JSON envelope reports a TimeoutError:
{"ok": false,"build": { "version": "0.1.0-dev", "date": "2026-04-27", "commit": "abc1234", "os": "darwin", "arch": "aarch64" },"stdout": "","stderr": "","output": [],"error": {"type": "TimeoutError","message": "Execution timed out after 100ms","line": null,"column": null,"fileName": null},"timing": { "lex_ns": 100000, "parse_ns": 200000, "compile_ns": 0, "exec_ns": 100000000, "total_ns": 100300000 },"memory": {"gc": {"liveBytes": 8192,"startLiveBytes": 0,"endLiveBytes": 8192,"peakLiveBytes": 16384,"deltaLiveBytes": 8192,"allocatedDuringRunBytes": 16384,"limitBytes": 536870912,"startObjectCount": 0,"endObjectCount": 80,"collections": 0,"collectedObjects": 0},"heap": {"startAllocatedBytes": 16384,"endAllocatedBytes": 32768,"deltaAllocatedBytes": 16384,"startFreeBytes": 8192,"endFreeBytes": 4096,"deltaFreeBytes": -4096}},"workers": { "used": 1, "available": 1, "parallel": false },"files": [{"fileName": "<stdin>","ok": false,"stdout": "","stderr": "","output": [],"error": {"type": "TimeoutError","message": "Execution timed out after 100ms","line": null,"column": null,"fileName": null},"timing": { "lex_ns": 100000, "parse_ns": 200000, "compile_ns": 0, "exec_ns": 100000000, "total_ns": 100300000 },"memory": { "gc": { "liveBytes": 8192 }, "heap": { "endAllocatedBytes": 32768 } },"result": null}]}
Embedding
For Pascal-side error handling when embedding GocciaScript in FreePascal applications, see Embedding the Engine. The engine raises TGocciaError subclasses (TGocciaSyntaxError and its subclass TGocciaLexerError, TGocciaTypeError, TGocciaReferenceError) on the Pascal side and TGocciaThrowValue for JS-level throw statements.
Related Documents
- Language -- Implemented features, recommended defaults, compatibility paths, and rationale
- Built-in Objects -- Error constructors and API reference
- Embedding the Engine -- Pascal-side error handling for embedders
- Testing -- Writing tests that assert on error behavior