@blokjs/shared 0.2.1 → 0.2.2
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/__tests__/unit/BlokError.test.ts +294 -0
- package/__tests__/unit/NodeBase.test.ts +4 -1
- package/dist/BlokError.d.ts +196 -0
- package/dist/BlokError.js +328 -0
- package/dist/BlokError.js.map +1 -0
- package/dist/NodeBase.d.ts +38 -2
- package/dist/NodeBase.js +41 -1
- package/dist/NodeBase.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/types/Context.d.ts +74 -0
- package/dist/types/StateContext.d.ts +21 -0
- package/dist/types/StateContext.js +2 -0
- package/dist/types/StateContext.js.map +1 -0
- package/dist/types/VarsContext.d.ts +15 -2
- package/package.json +2 -5
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import BlokError, {
|
|
3
|
+
DEFAULT_HTTP_STATUS,
|
|
4
|
+
DEFAULT_RETRYABLE,
|
|
5
|
+
ErrorCategory,
|
|
6
|
+
ErrorSeverity,
|
|
7
|
+
type NodeErrorPayload,
|
|
8
|
+
} from "../../src/BlokError";
|
|
9
|
+
import GlobalError from "../../src/GlobalError";
|
|
10
|
+
|
|
11
|
+
describe("BlokError", () => {
|
|
12
|
+
describe("factory methods", () => {
|
|
13
|
+
const factories = [
|
|
14
|
+
{ name: "validation", method: BlokError.validation, expected: ErrorCategory.VALIDATION },
|
|
15
|
+
{ name: "configuration", method: BlokError.configuration, expected: ErrorCategory.CONFIGURATION },
|
|
16
|
+
{ name: "dependency", method: BlokError.dependency, expected: ErrorCategory.DEPENDENCY },
|
|
17
|
+
{ name: "timeout", method: BlokError.timeout, expected: ErrorCategory.TIMEOUT },
|
|
18
|
+
{ name: "permission", method: BlokError.permission, expected: ErrorCategory.PERMISSION },
|
|
19
|
+
{ name: "rateLimit", method: BlokError.rateLimit, expected: ErrorCategory.RATE_LIMIT },
|
|
20
|
+
{ name: "notFound", method: BlokError.notFound, expected: ErrorCategory.NOT_FOUND },
|
|
21
|
+
{ name: "conflict", method: BlokError.conflict, expected: ErrorCategory.CONFLICT },
|
|
22
|
+
{ name: "cancelled", method: BlokError.cancelled, expected: ErrorCategory.CANCELLED },
|
|
23
|
+
{ name: "internal", method: BlokError.internal, expected: ErrorCategory.INTERNAL },
|
|
24
|
+
{ name: "protocol", method: BlokError.protocol, expected: ErrorCategory.PROTOCOL },
|
|
25
|
+
{ name: "data", method: BlokError.data, expected: ErrorCategory.DATA },
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
for (const { name, method, expected } of factories) {
|
|
29
|
+
it(`${name}() creates an error with the right category`, () => {
|
|
30
|
+
const err = method({ code: "TEST", message: "test" });
|
|
31
|
+
expect(err.category).toBe(expected);
|
|
32
|
+
expect(err).toBeInstanceOf(BlokError);
|
|
33
|
+
expect(err).toBeInstanceOf(GlobalError);
|
|
34
|
+
expect(err).toBeInstanceOf(Error);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
it("each factory applies the default http_status for its category", () => {
|
|
39
|
+
for (const { method, expected } of factories) {
|
|
40
|
+
const err = method({ code: "TEST", message: "test" });
|
|
41
|
+
expect(err.httpStatus).toBe(DEFAULT_HTTP_STATUS[expected]);
|
|
42
|
+
expect(err.context.code).toBe(DEFAULT_HTTP_STATUS[expected]);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("each factory applies the default retryable hint for its category", () => {
|
|
47
|
+
for (const { method, expected } of factories) {
|
|
48
|
+
const err = method({ code: "TEST", message: "test" });
|
|
49
|
+
expect(err.retryable).toBe(DEFAULT_RETRYABLE[expected]);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("defaults severity to ERROR", () => {
|
|
54
|
+
const err = BlokError.dependency({ code: "X", message: "x" });
|
|
55
|
+
expect(err.severity).toBe(ErrorSeverity.ERROR);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
describe("constructor options", () => {
|
|
60
|
+
it("preserves all human-readable fields", () => {
|
|
61
|
+
const err = BlokError.dependency({
|
|
62
|
+
code: "POSTGRES_CONNECT_TIMEOUT",
|
|
63
|
+
message: "Could not connect to Postgres within 5s",
|
|
64
|
+
description: "Tried host=localhost port=5432; timeout=5000ms",
|
|
65
|
+
remediation: "Check DATABASE_URL env var and network reachability",
|
|
66
|
+
docUrl: "https://blok.dev/errors/POSTGRES_CONNECT_TIMEOUT",
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
expect(err.errorCode).toBe("POSTGRES_CONNECT_TIMEOUT");
|
|
70
|
+
expect(err.message).toBe("Could not connect to Postgres within 5s");
|
|
71
|
+
expect(err.description).toContain("port=5432");
|
|
72
|
+
expect(err.remediation).toContain("DATABASE_URL");
|
|
73
|
+
expect(err.docUrl).toContain("POSTGRES_CONNECT_TIMEOUT");
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("allows overriding httpStatus", () => {
|
|
77
|
+
const err = BlokError.dependency({ code: "X", message: "x", httpStatus: 503 });
|
|
78
|
+
expect(err.httpStatus).toBe(503);
|
|
79
|
+
expect(err.context.code).toBe(503);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("allows overriding retryable + retryAfterMs", () => {
|
|
83
|
+
const err = BlokError.dependency({
|
|
84
|
+
code: "X",
|
|
85
|
+
message: "x",
|
|
86
|
+
retryable: false,
|
|
87
|
+
retryAfterMs: 0,
|
|
88
|
+
});
|
|
89
|
+
expect(err.retryable).toBe(false);
|
|
90
|
+
expect(err.retryAfterMs).toBe(0);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it("allows overriding severity", () => {
|
|
94
|
+
const err = BlokError.timeout({
|
|
95
|
+
code: "X",
|
|
96
|
+
message: "x",
|
|
97
|
+
severity: ErrorSeverity.FATAL,
|
|
98
|
+
});
|
|
99
|
+
expect(err.severity).toBe(ErrorSeverity.FATAL);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it("captures structured details", () => {
|
|
103
|
+
const err = BlokError.validation({
|
|
104
|
+
code: "VALIDATION_FAILED",
|
|
105
|
+
message: "schema mismatch",
|
|
106
|
+
details: { issues: [{ path: "email", message: "invalid" }] },
|
|
107
|
+
});
|
|
108
|
+
expect(err.details).toEqual({ issues: [{ path: "email", message: "invalid" }] });
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it("captures contextSnapshot", () => {
|
|
112
|
+
const snapshot = { inputs: { foo: "bar" }, varsKeys: ["a", "b"] };
|
|
113
|
+
const err = BlokError.internal({
|
|
114
|
+
code: "OOPS",
|
|
115
|
+
message: "oops",
|
|
116
|
+
contextSnapshot: snapshot,
|
|
117
|
+
});
|
|
118
|
+
expect(err.contextSnapshot).toEqual(snapshot);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe("cause chain", () => {
|
|
123
|
+
it("flattens a single Error cause", () => {
|
|
124
|
+
const inner = new Error("connect ECONNREFUSED");
|
|
125
|
+
const outer = BlokError.dependency({
|
|
126
|
+
code: "DB_DOWN",
|
|
127
|
+
message: "Database unreachable",
|
|
128
|
+
cause: inner,
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
expect(outer.causes).toHaveLength(1);
|
|
132
|
+
expect(outer.causes[0].message).toBe("connect ECONNREFUSED");
|
|
133
|
+
expect(outer.causes[0].category).toBe(ErrorCategory.INTERNAL);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("flattens a BlokError cause without re-wrapping its own causes", () => {
|
|
137
|
+
const root = BlokError.timeout({ code: "DNS_TIMEOUT", message: "dns timed out" });
|
|
138
|
+
const middle = BlokError.dependency({ code: "DB_DOWN", message: "db unreachable", cause: root });
|
|
139
|
+
const top = BlokError.internal({ code: "REQUEST_FAILED", message: "request failed", cause: middle });
|
|
140
|
+
|
|
141
|
+
expect(top.causes).toHaveLength(2);
|
|
142
|
+
expect(top.causes[0].code).toBe("DB_DOWN");
|
|
143
|
+
expect(top.causes[1].code).toBe("DNS_TIMEOUT");
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("returns an empty causes array when no cause is provided", () => {
|
|
147
|
+
const err = BlokError.internal({ code: "X", message: "x" });
|
|
148
|
+
expect(err.causes).toHaveLength(0);
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it("does not infinite-loop on circular causes", () => {
|
|
152
|
+
const a = new Error("a");
|
|
153
|
+
const b = new Error("b");
|
|
154
|
+
(a as Error & { cause?: Error }).cause = b;
|
|
155
|
+
(b as Error & { cause?: Error }).cause = a;
|
|
156
|
+
|
|
157
|
+
expect(() => BlokError.internal({ code: "CYCLE", message: "circular", cause: a })).not.toThrow();
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe("GlobalError compatibility", () => {
|
|
162
|
+
it("populates context.code with httpStatus", () => {
|
|
163
|
+
const err = BlokError.notFound({ code: "USER_NOT_FOUND", message: "no user" });
|
|
164
|
+
expect(err.context.code).toBe(404);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("populates context.name with node when provided", () => {
|
|
168
|
+
const err = BlokError.dependency({ code: "X", message: "x", node: "fetch-user" });
|
|
169
|
+
expect(err.context.name).toBe("fetch-user");
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
it("populates context.json with the full payload", () => {
|
|
173
|
+
const err = BlokError.dependency({
|
|
174
|
+
code: "DB_DOWN",
|
|
175
|
+
message: "db down",
|
|
176
|
+
description: "host unreachable",
|
|
177
|
+
remediation: "check network",
|
|
178
|
+
});
|
|
179
|
+
const payload = err.context.json as unknown as NodeErrorPayload;
|
|
180
|
+
expect(payload.code).toBe("DB_DOWN");
|
|
181
|
+
expect(payload.category).toBe(ErrorCategory.DEPENDENCY);
|
|
182
|
+
expect(payload.description).toBe("host unreachable");
|
|
183
|
+
expect(payload.remediation).toBe("check network");
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
describe("toJSON / fromJSON round-trip", () => {
|
|
188
|
+
it("preserves every field", () => {
|
|
189
|
+
const inner = BlokError.timeout({
|
|
190
|
+
code: "INNER_TIMEOUT",
|
|
191
|
+
message: "inner timed out",
|
|
192
|
+
});
|
|
193
|
+
const original = BlokError.dependency({
|
|
194
|
+
code: "DB_DOWN",
|
|
195
|
+
message: "Database unreachable",
|
|
196
|
+
description: "Tried host=db port=5432",
|
|
197
|
+
remediation: "Check DATABASE_URL",
|
|
198
|
+
docUrl: "https://blok.dev/errors/DB_DOWN",
|
|
199
|
+
cause: inner,
|
|
200
|
+
retryable: true,
|
|
201
|
+
retryAfterMs: 5000,
|
|
202
|
+
details: { sqlState: "08001" },
|
|
203
|
+
contextSnapshot: { inputs: { query: "SELECT 1" } },
|
|
204
|
+
httpStatus: 503,
|
|
205
|
+
severity: ErrorSeverity.WARN,
|
|
206
|
+
node: "store-tutorial",
|
|
207
|
+
sdk: "blok-python3",
|
|
208
|
+
sdkVersion: "1.0.0",
|
|
209
|
+
runtimeKind: "runtime.python3",
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
const json = original.toJSON();
|
|
213
|
+
const restored = BlokError.fromJSON(json);
|
|
214
|
+
|
|
215
|
+
expect(restored.errorCode).toBe(original.errorCode);
|
|
216
|
+
expect(restored.category).toBe(original.category);
|
|
217
|
+
expect(restored.severity).toBe(original.severity);
|
|
218
|
+
expect(restored.message).toBe(original.message);
|
|
219
|
+
expect(restored.description).toBe(original.description);
|
|
220
|
+
expect(restored.remediation).toBe(original.remediation);
|
|
221
|
+
expect(restored.docUrl).toBe(original.docUrl);
|
|
222
|
+
expect(restored.retryable).toBe(original.retryable);
|
|
223
|
+
expect(restored.retryAfterMs).toBe(original.retryAfterMs);
|
|
224
|
+
expect(restored.details).toEqual(original.details);
|
|
225
|
+
expect(restored.contextSnapshot).toEqual(original.contextSnapshot);
|
|
226
|
+
expect(restored.httpStatus).toBe(original.httpStatus);
|
|
227
|
+
expect(restored.nodeName).toBe(original.nodeName);
|
|
228
|
+
expect(restored.sdk).toBe(original.sdk);
|
|
229
|
+
expect(restored.sdkVersion).toBe(original.sdkVersion);
|
|
230
|
+
expect(restored.runtimeKind).toBe(original.runtimeKind);
|
|
231
|
+
expect(restored.causes).toEqual(original.causes);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it("toJSON produces an ISO timestamp for `at`", () => {
|
|
235
|
+
const err = BlokError.internal({ code: "X", message: "x" });
|
|
236
|
+
const json = err.toJSON();
|
|
237
|
+
expect(json.at).toMatch(/^\d{4}-\d{2}-\d{2}T/);
|
|
238
|
+
expect(new Date(json.at).getTime()).not.toBeNaN();
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
describe("fromUnknown", () => {
|
|
243
|
+
it("passes BlokError through unchanged", () => {
|
|
244
|
+
const original = BlokError.dependency({ code: "X", message: "x" });
|
|
245
|
+
const wrapped = BlokError.fromUnknown(original);
|
|
246
|
+
expect(wrapped).toBe(original);
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it("wraps a plain Error as INTERNAL with UNCAUGHT_<NAME> code", () => {
|
|
250
|
+
const err = new TypeError("bad type");
|
|
251
|
+
const wrapped = BlokError.fromUnknown(err);
|
|
252
|
+
expect(wrapped.category).toBe(ErrorCategory.INTERNAL);
|
|
253
|
+
expect(wrapped.errorCode).toBe("UNCAUGHT_TYPEERROR");
|
|
254
|
+
expect(wrapped.message).toBe("bad type");
|
|
255
|
+
expect(wrapped.causes).toHaveLength(1);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it("wraps a string as INTERNAL/UNCAUGHT_ERROR", () => {
|
|
259
|
+
const wrapped = BlokError.fromUnknown("oops");
|
|
260
|
+
expect(wrapped.category).toBe(ErrorCategory.INTERNAL);
|
|
261
|
+
expect(wrapped.errorCode).toBe("UNCAUGHT_ERROR");
|
|
262
|
+
expect(wrapped.message).toBe("oops");
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it("wraps a non-Error value as INTERNAL/UNCAUGHT_ERROR with stringified message", () => {
|
|
266
|
+
const wrapped = BlokError.fromUnknown({ weird: true });
|
|
267
|
+
expect(wrapped.category).toBe(ErrorCategory.INTERNAL);
|
|
268
|
+
expect(wrapped.errorCode).toBe("UNCAUGHT_ERROR");
|
|
269
|
+
expect(wrapped.message).toContain("weird");
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
it("preserves a pre-existing GlobalError code and json", () => {
|
|
273
|
+
const ge = new GlobalError("legacy");
|
|
274
|
+
ge.setCode(403);
|
|
275
|
+
ge.setJson({ origin: "auth" });
|
|
276
|
+
const wrapped = BlokError.fromUnknown(ge);
|
|
277
|
+
expect(wrapped.httpStatus).toBe(403);
|
|
278
|
+
expect(wrapped.details).toEqual({ origin: "auth" });
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
it("uses ctx overrides for node/sdk/sdkVersion/runtimeKind", () => {
|
|
282
|
+
const wrapped = BlokError.fromUnknown(new Error("x"), {
|
|
283
|
+
node: "step-1",
|
|
284
|
+
sdk: "blok-go",
|
|
285
|
+
sdkVersion: "1.0.0",
|
|
286
|
+
runtimeKind: "runtime.go",
|
|
287
|
+
});
|
|
288
|
+
expect(wrapped.nodeName).toBe("step-1");
|
|
289
|
+
expect(wrapped.sdk).toBe("blok-go");
|
|
290
|
+
expect(wrapped.sdkVersion).toBe("1.0.0");
|
|
291
|
+
expect(wrapped.runtimeKind).toBe("runtime.go");
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
});
|
|
@@ -46,7 +46,10 @@ describe("NodeBase", () => {
|
|
|
46
46
|
expect(n.name).toBe("");
|
|
47
47
|
expect(n.active).toBe(true);
|
|
48
48
|
expect(n.stop).toBe(false);
|
|
49
|
-
|
|
49
|
+
// set_var defaults to undefined (NOT false). false short-circuits
|
|
50
|
+
// PersistenceHelper.applyStepOutput and silently disables v2's
|
|
51
|
+
// default-store rule for every step that didn't explicitly set it.
|
|
52
|
+
expect(n.set_var).toBeUndefined();
|
|
50
53
|
expect(n.contentType).toBe("");
|
|
51
54
|
});
|
|
52
55
|
});
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import GlobalError from "./GlobalError";
|
|
2
|
+
/**
|
|
3
|
+
* The categories every Blok node error falls into.
|
|
4
|
+
*
|
|
5
|
+
* Mirror of the proto `blok.runtime.v1.ErrorCategory` enum. Stored as string
|
|
6
|
+
* values so JSON payloads (e.g. `GlobalError.context.json`) are human-readable.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ErrorCategory: {
|
|
9
|
+
readonly VALIDATION: "VALIDATION";
|
|
10
|
+
readonly CONFIGURATION: "CONFIGURATION";
|
|
11
|
+
readonly DEPENDENCY: "DEPENDENCY";
|
|
12
|
+
readonly TIMEOUT: "TIMEOUT";
|
|
13
|
+
readonly PERMISSION: "PERMISSION";
|
|
14
|
+
readonly RATE_LIMIT: "RATE_LIMIT";
|
|
15
|
+
readonly NOT_FOUND: "NOT_FOUND";
|
|
16
|
+
readonly CONFLICT: "CONFLICT";
|
|
17
|
+
readonly CANCELLED: "CANCELLED";
|
|
18
|
+
readonly INTERNAL: "INTERNAL";
|
|
19
|
+
readonly PROTOCOL: "PROTOCOL";
|
|
20
|
+
readonly DATA: "DATA";
|
|
21
|
+
};
|
|
22
|
+
export type ErrorCategory = (typeof ErrorCategory)[keyof typeof ErrorCategory];
|
|
23
|
+
/** How severe an error is. Default for thrown errors is `ERROR`. */
|
|
24
|
+
export declare const ErrorSeverity: {
|
|
25
|
+
readonly INFO: "INFO";
|
|
26
|
+
readonly WARN: "WARN";
|
|
27
|
+
readonly ERROR: "ERROR";
|
|
28
|
+
readonly FATAL: "FATAL";
|
|
29
|
+
};
|
|
30
|
+
export type ErrorSeverity = (typeof ErrorSeverity)[keyof typeof ErrorSeverity];
|
|
31
|
+
/**
|
|
32
|
+
* Default HTTP status per error category.
|
|
33
|
+
*
|
|
34
|
+
* Single source of truth — the runner uses these on `GlobalError.context.code`
|
|
35
|
+
* and HTTP triggers use them as the response status. Override per-error via
|
|
36
|
+
* `BlokErrorOpts.httpStatus`.
|
|
37
|
+
*/
|
|
38
|
+
export declare const DEFAULT_HTTP_STATUS: Readonly<Record<ErrorCategory, number>>;
|
|
39
|
+
/** Default retryable hint per error category. */
|
|
40
|
+
export declare const DEFAULT_RETRYABLE: Readonly<Record<ErrorCategory, boolean>>;
|
|
41
|
+
/**
|
|
42
|
+
* The plain-data shape of a Blok node error.
|
|
43
|
+
*
|
|
44
|
+
* 1:1 mirror of the proto `blok.runtime.v1.NodeError` message in JSON form.
|
|
45
|
+
* The runner-side gRPC codec converts between this shape and the proto type;
|
|
46
|
+
* this module has no gRPC dependency.
|
|
47
|
+
*/
|
|
48
|
+
export interface NodeErrorPayload {
|
|
49
|
+
/** Stable machine identifier — see `docs/error-codes.md`. */
|
|
50
|
+
code: string;
|
|
51
|
+
category: ErrorCategory;
|
|
52
|
+
severity: ErrorSeverity;
|
|
53
|
+
/** Node name that produced this error (auto-filled by SDKs). */
|
|
54
|
+
node: string;
|
|
55
|
+
/** SDK identifier, e.g. "blok-python3" (auto-filled). */
|
|
56
|
+
sdk: string;
|
|
57
|
+
sdkVersion: string;
|
|
58
|
+
/** Runtime kind, e.g. "runtime.python3" (auto-filled). */
|
|
59
|
+
runtimeKind: string;
|
|
60
|
+
/** ISO 8601 timestamp of the error. */
|
|
61
|
+
at: string;
|
|
62
|
+
message: string;
|
|
63
|
+
description: string;
|
|
64
|
+
remediation: string;
|
|
65
|
+
docUrl: string;
|
|
66
|
+
/** Flattened cause chain — outermost cause first. */
|
|
67
|
+
causes: NodeErrorPayload[];
|
|
68
|
+
stack: string;
|
|
69
|
+
/** Bounded slice of resolved inputs/state at error time. */
|
|
70
|
+
contextSnapshot: unknown;
|
|
71
|
+
httpStatus: number;
|
|
72
|
+
retryable: boolean;
|
|
73
|
+
retryAfterMs: number;
|
|
74
|
+
/** Category-specific structured details (Zod issues, SQL state, etc.). */
|
|
75
|
+
details: unknown;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Constructor options for {@link BlokError}.
|
|
79
|
+
*
|
|
80
|
+
* `code`, `message`, and the implicit `category` (via the factory method) are
|
|
81
|
+
* the seven required fields that, combined with auto-filled origin, make every
|
|
82
|
+
* error self-describing.
|
|
83
|
+
*/
|
|
84
|
+
export interface BlokErrorOpts {
|
|
85
|
+
/** Stable machine identifier (e.g. "POSTGRES_CONNECT_TIMEOUT"). */
|
|
86
|
+
code: string;
|
|
87
|
+
/** One-sentence human summary. */
|
|
88
|
+
message: string;
|
|
89
|
+
/** Multi-paragraph context: what was tried, why it failed. */
|
|
90
|
+
description?: string;
|
|
91
|
+
/** Suggested next step for the developer. */
|
|
92
|
+
remediation?: string;
|
|
93
|
+
/** Optional link to documentation explaining this code. */
|
|
94
|
+
docUrl?: string;
|
|
95
|
+
/** Underlying cause — any Error or BlokError. */
|
|
96
|
+
cause?: Error | BlokError;
|
|
97
|
+
/** Override default retryable hint. */
|
|
98
|
+
retryable?: boolean;
|
|
99
|
+
/** Suggested wait time before retrying. */
|
|
100
|
+
retryAfterMs?: number;
|
|
101
|
+
/** Category-specific structured details. */
|
|
102
|
+
details?: unknown;
|
|
103
|
+
/** Bounded slice of inputs/state at error time. */
|
|
104
|
+
contextSnapshot?: unknown;
|
|
105
|
+
/** Override the default HTTP status for this category. */
|
|
106
|
+
httpStatus?: number;
|
|
107
|
+
/** Override the default severity (`ERROR`). */
|
|
108
|
+
severity?: ErrorSeverity;
|
|
109
|
+
/** Override the auto-filled node name. */
|
|
110
|
+
node?: string;
|
|
111
|
+
/** Override the auto-filled SDK name. */
|
|
112
|
+
sdk?: string;
|
|
113
|
+
/** Override the auto-filled SDK version. */
|
|
114
|
+
sdkVersion?: string;
|
|
115
|
+
/** Override the auto-filled runtime kind. */
|
|
116
|
+
runtimeKind?: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Structured error type for Blok nodes. Extends {@link GlobalError} so it
|
|
120
|
+
* remains fully compatible with existing `instanceof GlobalError` checks and
|
|
121
|
+
* `GlobalError.context` consumers (HTTP trigger, RunTracker, Studio).
|
|
122
|
+
*
|
|
123
|
+
* Use the static factory methods (`BlokError.validation`,
|
|
124
|
+
* `BlokError.dependency`, etc.) — direct construction is private.
|
|
125
|
+
*
|
|
126
|
+
* Auto-fills `name`, `stack`, and `at`. The runner enriches `node`, `sdk`,
|
|
127
|
+
* `sdkVersion`, and `runtimeKind` when the error is sourced from a runtime
|
|
128
|
+
* adapter; module nodes can override via {@link BlokErrorOpts}.
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* throw BlokError.dependency({
|
|
132
|
+
* code: "POSTGRES_CONNECT_TIMEOUT",
|
|
133
|
+
* message: "Could not connect to Postgres within 5s",
|
|
134
|
+
* description: `Tried host=${host} port=${port}; timeout=${dur}ms`,
|
|
135
|
+
* remediation: "Check DATABASE_URL env var and network reachability",
|
|
136
|
+
* cause: err,
|
|
137
|
+
* });
|
|
138
|
+
*/
|
|
139
|
+
export default class BlokError extends GlobalError {
|
|
140
|
+
readonly category: ErrorCategory;
|
|
141
|
+
readonly severity: ErrorSeverity;
|
|
142
|
+
readonly errorCode: string;
|
|
143
|
+
readonly description: string;
|
|
144
|
+
readonly remediation: string;
|
|
145
|
+
readonly docUrl: string;
|
|
146
|
+
readonly retryable: boolean;
|
|
147
|
+
readonly retryAfterMs: number;
|
|
148
|
+
readonly details: unknown;
|
|
149
|
+
readonly contextSnapshot: unknown;
|
|
150
|
+
readonly causes: ReadonlyArray<NodeErrorPayload>;
|
|
151
|
+
readonly at: Date;
|
|
152
|
+
readonly sdk: string;
|
|
153
|
+
readonly sdkVersion: string;
|
|
154
|
+
readonly runtimeKind: string;
|
|
155
|
+
readonly httpStatus: number;
|
|
156
|
+
readonly nodeName: string;
|
|
157
|
+
private constructor();
|
|
158
|
+
static validation(opts: BlokErrorOpts): BlokError;
|
|
159
|
+
static configuration(opts: BlokErrorOpts): BlokError;
|
|
160
|
+
static dependency(opts: BlokErrorOpts): BlokError;
|
|
161
|
+
static timeout(opts: BlokErrorOpts): BlokError;
|
|
162
|
+
static permission(opts: BlokErrorOpts): BlokError;
|
|
163
|
+
static rateLimit(opts: BlokErrorOpts): BlokError;
|
|
164
|
+
static notFound(opts: BlokErrorOpts): BlokError;
|
|
165
|
+
static conflict(opts: BlokErrorOpts): BlokError;
|
|
166
|
+
static cancelled(opts: BlokErrorOpts): BlokError;
|
|
167
|
+
static internal(opts: BlokErrorOpts): BlokError;
|
|
168
|
+
static protocol(opts: BlokErrorOpts): BlokError;
|
|
169
|
+
static data(opts: BlokErrorOpts): BlokError;
|
|
170
|
+
/**
|
|
171
|
+
* Convert any thrown value into a `BlokError`.
|
|
172
|
+
*
|
|
173
|
+
* Used by the runner's auto-wrap layer so legacy code (`throw new
|
|
174
|
+
* Error("oops")`) still produces a structured error. Categorization is
|
|
175
|
+
* heuristic — recognizes existing `BlokError` (passthrough), `GlobalError`
|
|
176
|
+
* (preserves code/json), `Error` (wraps as `INTERNAL`), and anything else
|
|
177
|
+
* (stringified as `INTERNAL`).
|
|
178
|
+
*/
|
|
179
|
+
static fromUnknown(err: unknown, ctx?: {
|
|
180
|
+
node?: string;
|
|
181
|
+
sdk?: string;
|
|
182
|
+
sdkVersion?: string;
|
|
183
|
+
runtimeKind?: string;
|
|
184
|
+
}): BlokError;
|
|
185
|
+
/**
|
|
186
|
+
* Reconstruct a `BlokError` from a serialized {@link NodeErrorPayload}.
|
|
187
|
+
*
|
|
188
|
+
* Used by the runner's gRPC codec to convert proto `NodeError` messages
|
|
189
|
+
* received from SDKs back into TS-side errors.
|
|
190
|
+
*/
|
|
191
|
+
static fromJSON(payload: NodeErrorPayload): BlokError;
|
|
192
|
+
/** Serialize to the canonical {@link NodeErrorPayload} shape (matches proto wire format). */
|
|
193
|
+
toJSON(): NodeErrorPayload;
|
|
194
|
+
private static flattenCauses;
|
|
195
|
+
private static causeToPayload;
|
|
196
|
+
}
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
import GlobalError from "./GlobalError";
|
|
2
|
+
/**
|
|
3
|
+
* The categories every Blok node error falls into.
|
|
4
|
+
*
|
|
5
|
+
* Mirror of the proto `blok.runtime.v1.ErrorCategory` enum. Stored as string
|
|
6
|
+
* values so JSON payloads (e.g. `GlobalError.context.json`) are human-readable.
|
|
7
|
+
*/
|
|
8
|
+
export const ErrorCategory = {
|
|
9
|
+
VALIDATION: "VALIDATION",
|
|
10
|
+
CONFIGURATION: "CONFIGURATION",
|
|
11
|
+
DEPENDENCY: "DEPENDENCY",
|
|
12
|
+
TIMEOUT: "TIMEOUT",
|
|
13
|
+
PERMISSION: "PERMISSION",
|
|
14
|
+
RATE_LIMIT: "RATE_LIMIT",
|
|
15
|
+
NOT_FOUND: "NOT_FOUND",
|
|
16
|
+
CONFLICT: "CONFLICT",
|
|
17
|
+
CANCELLED: "CANCELLED",
|
|
18
|
+
INTERNAL: "INTERNAL",
|
|
19
|
+
PROTOCOL: "PROTOCOL",
|
|
20
|
+
DATA: "DATA",
|
|
21
|
+
};
|
|
22
|
+
/** How severe an error is. Default for thrown errors is `ERROR`. */
|
|
23
|
+
export const ErrorSeverity = {
|
|
24
|
+
INFO: "INFO",
|
|
25
|
+
WARN: "WARN",
|
|
26
|
+
ERROR: "ERROR",
|
|
27
|
+
FATAL: "FATAL",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Default HTTP status per error category.
|
|
31
|
+
*
|
|
32
|
+
* Single source of truth — the runner uses these on `GlobalError.context.code`
|
|
33
|
+
* and HTTP triggers use them as the response status. Override per-error via
|
|
34
|
+
* `BlokErrorOpts.httpStatus`.
|
|
35
|
+
*/
|
|
36
|
+
export const DEFAULT_HTTP_STATUS = {
|
|
37
|
+
VALIDATION: 400,
|
|
38
|
+
CONFIGURATION: 500,
|
|
39
|
+
DEPENDENCY: 502,
|
|
40
|
+
TIMEOUT: 504,
|
|
41
|
+
PERMISSION: 403,
|
|
42
|
+
RATE_LIMIT: 429,
|
|
43
|
+
NOT_FOUND: 404,
|
|
44
|
+
CONFLICT: 409,
|
|
45
|
+
CANCELLED: 499,
|
|
46
|
+
INTERNAL: 500,
|
|
47
|
+
PROTOCOL: 502,
|
|
48
|
+
DATA: 422,
|
|
49
|
+
};
|
|
50
|
+
/** Default retryable hint per error category. */
|
|
51
|
+
export const DEFAULT_RETRYABLE = {
|
|
52
|
+
VALIDATION: false,
|
|
53
|
+
CONFIGURATION: false,
|
|
54
|
+
DEPENDENCY: true,
|
|
55
|
+
TIMEOUT: true,
|
|
56
|
+
PERMISSION: false,
|
|
57
|
+
RATE_LIMIT: true,
|
|
58
|
+
NOT_FOUND: false,
|
|
59
|
+
CONFLICT: false,
|
|
60
|
+
CANCELLED: false,
|
|
61
|
+
INTERNAL: false,
|
|
62
|
+
PROTOCOL: false,
|
|
63
|
+
DATA: false,
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Structured error type for Blok nodes. Extends {@link GlobalError} so it
|
|
67
|
+
* remains fully compatible with existing `instanceof GlobalError` checks and
|
|
68
|
+
* `GlobalError.context` consumers (HTTP trigger, RunTracker, Studio).
|
|
69
|
+
*
|
|
70
|
+
* Use the static factory methods (`BlokError.validation`,
|
|
71
|
+
* `BlokError.dependency`, etc.) — direct construction is private.
|
|
72
|
+
*
|
|
73
|
+
* Auto-fills `name`, `stack`, and `at`. The runner enriches `node`, `sdk`,
|
|
74
|
+
* `sdkVersion`, and `runtimeKind` when the error is sourced from a runtime
|
|
75
|
+
* adapter; module nodes can override via {@link BlokErrorOpts}.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* throw BlokError.dependency({
|
|
79
|
+
* code: "POSTGRES_CONNECT_TIMEOUT",
|
|
80
|
+
* message: "Could not connect to Postgres within 5s",
|
|
81
|
+
* description: `Tried host=${host} port=${port}; timeout=${dur}ms`,
|
|
82
|
+
* remediation: "Check DATABASE_URL env var and network reachability",
|
|
83
|
+
* cause: err,
|
|
84
|
+
* });
|
|
85
|
+
*/
|
|
86
|
+
export default class BlokError extends GlobalError {
|
|
87
|
+
category;
|
|
88
|
+
severity;
|
|
89
|
+
errorCode;
|
|
90
|
+
description;
|
|
91
|
+
remediation;
|
|
92
|
+
docUrl;
|
|
93
|
+
retryable;
|
|
94
|
+
retryAfterMs;
|
|
95
|
+
details;
|
|
96
|
+
contextSnapshot;
|
|
97
|
+
causes;
|
|
98
|
+
at;
|
|
99
|
+
sdk;
|
|
100
|
+
sdkVersion;
|
|
101
|
+
runtimeKind;
|
|
102
|
+
httpStatus;
|
|
103
|
+
nodeName;
|
|
104
|
+
constructor(category, opts) {
|
|
105
|
+
super(opts.message);
|
|
106
|
+
Object.setPrototypeOf(this, BlokError.prototype);
|
|
107
|
+
this.category = category;
|
|
108
|
+
this.severity = opts.severity ?? ErrorSeverity.ERROR;
|
|
109
|
+
this.errorCode = opts.code;
|
|
110
|
+
this.description = opts.description ?? "";
|
|
111
|
+
this.remediation = opts.remediation ?? "";
|
|
112
|
+
this.docUrl = opts.docUrl ?? "";
|
|
113
|
+
this.retryable = opts.retryable ?? DEFAULT_RETRYABLE[category];
|
|
114
|
+
this.retryAfterMs = opts.retryAfterMs ?? 0;
|
|
115
|
+
this.details = opts.details ?? null;
|
|
116
|
+
this.contextSnapshot = opts.contextSnapshot ?? null;
|
|
117
|
+
this.at = new Date();
|
|
118
|
+
this.sdk = opts.sdk ?? "";
|
|
119
|
+
this.sdkVersion = opts.sdkVersion ?? "";
|
|
120
|
+
this.runtimeKind = opts.runtimeKind ?? "";
|
|
121
|
+
this.nodeName = opts.node ?? "";
|
|
122
|
+
this.httpStatus = opts.httpStatus ?? DEFAULT_HTTP_STATUS[category];
|
|
123
|
+
this.causes = opts.cause ? Object.freeze(BlokError.flattenCauses(opts.cause)) : Object.freeze([]);
|
|
124
|
+
// Populate the GlobalError.context fields so legacy consumers keep working.
|
|
125
|
+
this.setCode(this.httpStatus);
|
|
126
|
+
this.setName(this.nodeName);
|
|
127
|
+
this.setStack(this.stack);
|
|
128
|
+
this.setJson(this.toJSON());
|
|
129
|
+
}
|
|
130
|
+
// =========================================================================
|
|
131
|
+
// Factory methods (one per category)
|
|
132
|
+
// =========================================================================
|
|
133
|
+
static validation(opts) {
|
|
134
|
+
return new BlokError(ErrorCategory.VALIDATION, opts);
|
|
135
|
+
}
|
|
136
|
+
static configuration(opts) {
|
|
137
|
+
return new BlokError(ErrorCategory.CONFIGURATION, opts);
|
|
138
|
+
}
|
|
139
|
+
static dependency(opts) {
|
|
140
|
+
return new BlokError(ErrorCategory.DEPENDENCY, opts);
|
|
141
|
+
}
|
|
142
|
+
static timeout(opts) {
|
|
143
|
+
return new BlokError(ErrorCategory.TIMEOUT, opts);
|
|
144
|
+
}
|
|
145
|
+
static permission(opts) {
|
|
146
|
+
return new BlokError(ErrorCategory.PERMISSION, opts);
|
|
147
|
+
}
|
|
148
|
+
static rateLimit(opts) {
|
|
149
|
+
return new BlokError(ErrorCategory.RATE_LIMIT, opts);
|
|
150
|
+
}
|
|
151
|
+
static notFound(opts) {
|
|
152
|
+
return new BlokError(ErrorCategory.NOT_FOUND, opts);
|
|
153
|
+
}
|
|
154
|
+
static conflict(opts) {
|
|
155
|
+
return new BlokError(ErrorCategory.CONFLICT, opts);
|
|
156
|
+
}
|
|
157
|
+
static cancelled(opts) {
|
|
158
|
+
return new BlokError(ErrorCategory.CANCELLED, opts);
|
|
159
|
+
}
|
|
160
|
+
static internal(opts) {
|
|
161
|
+
return new BlokError(ErrorCategory.INTERNAL, opts);
|
|
162
|
+
}
|
|
163
|
+
static protocol(opts) {
|
|
164
|
+
return new BlokError(ErrorCategory.PROTOCOL, opts);
|
|
165
|
+
}
|
|
166
|
+
static data(opts) {
|
|
167
|
+
return new BlokError(ErrorCategory.DATA, opts);
|
|
168
|
+
}
|
|
169
|
+
// =========================================================================
|
|
170
|
+
// Conversion
|
|
171
|
+
// =========================================================================
|
|
172
|
+
/**
|
|
173
|
+
* Convert any thrown value into a `BlokError`.
|
|
174
|
+
*
|
|
175
|
+
* Used by the runner's auto-wrap layer so legacy code (`throw new
|
|
176
|
+
* Error("oops")`) still produces a structured error. Categorization is
|
|
177
|
+
* heuristic — recognizes existing `BlokError` (passthrough), `GlobalError`
|
|
178
|
+
* (preserves code/json), `Error` (wraps as `INTERNAL`), and anything else
|
|
179
|
+
* (stringified as `INTERNAL`).
|
|
180
|
+
*/
|
|
181
|
+
static fromUnknown(err, ctx) {
|
|
182
|
+
if (err instanceof BlokError) {
|
|
183
|
+
return err;
|
|
184
|
+
}
|
|
185
|
+
if (err instanceof GlobalError) {
|
|
186
|
+
const httpStatus = err.context.code ?? 500;
|
|
187
|
+
const wrapped = new BlokError(ErrorCategory.INTERNAL, {
|
|
188
|
+
code: "GLOBAL_ERROR",
|
|
189
|
+
message: err.message ?? "Unknown error",
|
|
190
|
+
details: err.context.json ?? null,
|
|
191
|
+
httpStatus,
|
|
192
|
+
node: ctx?.node ?? err.context.name ?? "",
|
|
193
|
+
sdk: ctx?.sdk,
|
|
194
|
+
sdkVersion: ctx?.sdkVersion,
|
|
195
|
+
runtimeKind: ctx?.runtimeKind,
|
|
196
|
+
});
|
|
197
|
+
if (err.stack)
|
|
198
|
+
wrapped.setStack(err.stack);
|
|
199
|
+
return wrapped;
|
|
200
|
+
}
|
|
201
|
+
if (err instanceof Error) {
|
|
202
|
+
return new BlokError(ErrorCategory.INTERNAL, {
|
|
203
|
+
code: `UNCAUGHT_${err.name || "ERROR"}`.toUpperCase(),
|
|
204
|
+
message: err.message || "Uncaught error",
|
|
205
|
+
cause: err,
|
|
206
|
+
node: ctx?.node,
|
|
207
|
+
sdk: ctx?.sdk,
|
|
208
|
+
sdkVersion: ctx?.sdkVersion,
|
|
209
|
+
runtimeKind: ctx?.runtimeKind,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
return new BlokError(ErrorCategory.INTERNAL, {
|
|
213
|
+
code: "UNCAUGHT_ERROR",
|
|
214
|
+
message: typeof err === "string" ? err : JSON.stringify(err),
|
|
215
|
+
node: ctx?.node,
|
|
216
|
+
sdk: ctx?.sdk,
|
|
217
|
+
sdkVersion: ctx?.sdkVersion,
|
|
218
|
+
runtimeKind: ctx?.runtimeKind,
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Reconstruct a `BlokError` from a serialized {@link NodeErrorPayload}.
|
|
223
|
+
*
|
|
224
|
+
* Used by the runner's gRPC codec to convert proto `NodeError` messages
|
|
225
|
+
* received from SDKs back into TS-side errors.
|
|
226
|
+
*/
|
|
227
|
+
static fromJSON(payload) {
|
|
228
|
+
const err = new BlokError(payload.category, {
|
|
229
|
+
code: payload.code,
|
|
230
|
+
message: payload.message,
|
|
231
|
+
description: payload.description,
|
|
232
|
+
remediation: payload.remediation,
|
|
233
|
+
docUrl: payload.docUrl,
|
|
234
|
+
retryable: payload.retryable,
|
|
235
|
+
retryAfterMs: payload.retryAfterMs,
|
|
236
|
+
details: payload.details,
|
|
237
|
+
contextSnapshot: payload.contextSnapshot,
|
|
238
|
+
httpStatus: payload.httpStatus,
|
|
239
|
+
severity: payload.severity,
|
|
240
|
+
node: payload.node,
|
|
241
|
+
sdk: payload.sdk,
|
|
242
|
+
sdkVersion: payload.sdkVersion,
|
|
243
|
+
runtimeKind: payload.runtimeKind,
|
|
244
|
+
});
|
|
245
|
+
if (payload.stack)
|
|
246
|
+
err.setStack(payload.stack);
|
|
247
|
+
// Restore frozen causes from payload (causes are NodeErrorPayload[], not BlokError).
|
|
248
|
+
err.causes = Object.freeze([...payload.causes]);
|
|
249
|
+
return err;
|
|
250
|
+
}
|
|
251
|
+
/** Serialize to the canonical {@link NodeErrorPayload} shape (matches proto wire format). */
|
|
252
|
+
toJSON() {
|
|
253
|
+
return {
|
|
254
|
+
code: this.errorCode,
|
|
255
|
+
category: this.category,
|
|
256
|
+
severity: this.severity,
|
|
257
|
+
node: this.nodeName,
|
|
258
|
+
sdk: this.sdk,
|
|
259
|
+
sdkVersion: this.sdkVersion,
|
|
260
|
+
runtimeKind: this.runtimeKind,
|
|
261
|
+
at: this.at.toISOString(),
|
|
262
|
+
message: this.message,
|
|
263
|
+
description: this.description,
|
|
264
|
+
remediation: this.remediation,
|
|
265
|
+
docUrl: this.docUrl,
|
|
266
|
+
causes: [...this.causes],
|
|
267
|
+
stack: this.stack ?? "",
|
|
268
|
+
contextSnapshot: this.contextSnapshot,
|
|
269
|
+
httpStatus: this.httpStatus,
|
|
270
|
+
retryable: this.retryable,
|
|
271
|
+
retryAfterMs: this.retryAfterMs,
|
|
272
|
+
details: this.details,
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
// =========================================================================
|
|
276
|
+
// Internal helpers
|
|
277
|
+
// =========================================================================
|
|
278
|
+
static flattenCauses(cause) {
|
|
279
|
+
const causes = [];
|
|
280
|
+
let current = cause;
|
|
281
|
+
const visited = new Set();
|
|
282
|
+
while (current && !visited.has(current)) {
|
|
283
|
+
visited.add(current);
|
|
284
|
+
if (current instanceof BlokError) {
|
|
285
|
+
// Append the BlokError's own payload (with `causes` zeroed out so we
|
|
286
|
+
// don't double-count) followed by its already-flattened causes. This
|
|
287
|
+
// keeps the final chain flat regardless of how deeply nested the
|
|
288
|
+
// caller's BlokError-as-cause chain was.
|
|
289
|
+
causes.push(BlokError.causeToPayload(current));
|
|
290
|
+
causes.push(...current.causes);
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
causes.push(BlokError.causeToPayload(current));
|
|
294
|
+
const nextCause = current.cause;
|
|
295
|
+
current = nextCause;
|
|
296
|
+
}
|
|
297
|
+
return causes;
|
|
298
|
+
}
|
|
299
|
+
static causeToPayload(cause) {
|
|
300
|
+
if (cause instanceof BlokError) {
|
|
301
|
+
// Strip the cause's own `causes` to avoid duplication — the caller
|
|
302
|
+
// (flattenCauses) appends them separately to keep the final list flat.
|
|
303
|
+
return { ...cause.toJSON(), causes: [] };
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
code: `UNCAUGHT_${cause.name || "ERROR"}`.toUpperCase(),
|
|
307
|
+
category: ErrorCategory.INTERNAL,
|
|
308
|
+
severity: ErrorSeverity.ERROR,
|
|
309
|
+
node: "",
|
|
310
|
+
sdk: "",
|
|
311
|
+
sdkVersion: "",
|
|
312
|
+
runtimeKind: "",
|
|
313
|
+
at: new Date().toISOString(),
|
|
314
|
+
message: cause.message || "Uncaught error",
|
|
315
|
+
description: "",
|
|
316
|
+
remediation: "",
|
|
317
|
+
docUrl: "",
|
|
318
|
+
causes: [],
|
|
319
|
+
stack: cause.stack ?? "",
|
|
320
|
+
contextSnapshot: null,
|
|
321
|
+
httpStatus: 500,
|
|
322
|
+
retryable: false,
|
|
323
|
+
retryAfterMs: 0,
|
|
324
|
+
details: null,
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
//# sourceMappingURL=BlokError.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BlokError.js","sourceRoot":"","sources":["../src/BlokError.ts"],"names":[],"mappings":"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"}
|
package/dist/NodeBase.d.ts
CHANGED
|
@@ -13,14 +13,50 @@ export default abstract class NodeBase {
|
|
|
13
13
|
active: boolean;
|
|
14
14
|
stop: boolean;
|
|
15
15
|
originalConfig: ParamsDictionary;
|
|
16
|
-
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated v2 default-stores every step's output. `set_var: true` is
|
|
18
|
+
* a no-op (default behaviour); `set_var: false` is normalized to
|
|
19
|
+
* `ephemeral: true` at workflow load time. Reading this field is still
|
|
20
|
+
* supported for legacy code paths but new code should rely on `ephemeral`.
|
|
21
|
+
*
|
|
22
|
+
* Default is `undefined` (NOT `false`) — `false` here would short-circuit
|
|
23
|
+
* `PersistenceHelper.applyStepOutput` and disable the v2 default-store
|
|
24
|
+
* rule for every step that didn't explicitly set the field.
|
|
25
|
+
*/
|
|
26
|
+
set_var?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Alternative state key for this step's output. When set, the runner
|
|
29
|
+
* stores result.data at `ctx.state[as]` instead of `ctx.state[name]`.
|
|
30
|
+
*/
|
|
31
|
+
as?: string;
|
|
32
|
+
/**
|
|
33
|
+
* When true, the runner shallow-merges the keys of result.data into
|
|
34
|
+
* `ctx.state` instead of nesting under the step name. Mutually exclusive
|
|
35
|
+
* with `as`.
|
|
36
|
+
*/
|
|
37
|
+
spread: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* When true, the runner skips persisting this step's output to state.
|
|
40
|
+
* Only `ctx.prev` carries the result to the immediately next step.
|
|
41
|
+
*/
|
|
42
|
+
ephemeral: boolean;
|
|
17
43
|
process(ctx: Context, step?: Step): Promise<ResponseContext>;
|
|
18
44
|
processFlow(ctx: Context): Promise<ResponseContext>;
|
|
19
45
|
abstract run(ctx: Context): Promise<ResponseContext>;
|
|
20
46
|
runSteps(step: Step | Step[], ctx: Context): Promise<Context>;
|
|
21
47
|
runJs(str: string, ctx: Context, data?: ParamsDictionary, func?: FunctionContext, vars?: VarsContext): ParamsDictionary;
|
|
48
|
+
/**
|
|
49
|
+
* @deprecated In v2, return your output and let the runner persist it
|
|
50
|
+
* to `ctx.state[id]` automatically. Use `ctx.publish(name, value)` for
|
|
51
|
+
* explicit side-channel publication when you really need it. This
|
|
52
|
+
* method continues to work for legacy code.
|
|
53
|
+
*/
|
|
22
54
|
setVar(ctx: Context, vars: VarsContext): void;
|
|
23
|
-
|
|
55
|
+
/**
|
|
56
|
+
* @deprecated Read from `ctx.state[name]` directly, or reference it from
|
|
57
|
+
* a workflow step's `inputs` as `$.state[name]` / `js/ctx.state.name`.
|
|
58
|
+
*/
|
|
59
|
+
getVar(ctx: Context, name: string): unknown;
|
|
24
60
|
blueprintMapper: (obj: ParamsDictionary, ctx: Context, data?: ParamsDictionary) => string | ParamsDictionary;
|
|
25
61
|
setError(config: ErrorContext): GlobalError;
|
|
26
62
|
}
|
package/dist/NodeBase.js
CHANGED
|
@@ -8,7 +8,37 @@ export default class NodeBase {
|
|
|
8
8
|
active = true;
|
|
9
9
|
stop = false;
|
|
10
10
|
originalConfig = {};
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* @deprecated v2 default-stores every step's output. `set_var: true` is
|
|
13
|
+
* a no-op (default behaviour); `set_var: false` is normalized to
|
|
14
|
+
* `ephemeral: true` at workflow load time. Reading this field is still
|
|
15
|
+
* supported for legacy code paths but new code should rely on `ephemeral`.
|
|
16
|
+
*
|
|
17
|
+
* Default is `undefined` (NOT `false`) — `false` here would short-circuit
|
|
18
|
+
* `PersistenceHelper.applyStepOutput` and disable the v2 default-store
|
|
19
|
+
* rule for every step that didn't explicitly set the field.
|
|
20
|
+
*/
|
|
21
|
+
set_var;
|
|
22
|
+
// =========================================================================
|
|
23
|
+
// V2 persistence knobs — populated by Configuration.getSteps from the
|
|
24
|
+
// step definition. Read by PersistenceHelper.applyStepOutput.
|
|
25
|
+
// =========================================================================
|
|
26
|
+
/**
|
|
27
|
+
* Alternative state key for this step's output. When set, the runner
|
|
28
|
+
* stores result.data at `ctx.state[as]` instead of `ctx.state[name]`.
|
|
29
|
+
*/
|
|
30
|
+
as;
|
|
31
|
+
/**
|
|
32
|
+
* When true, the runner shallow-merges the keys of result.data into
|
|
33
|
+
* `ctx.state` instead of nesting under the step name. Mutually exclusive
|
|
34
|
+
* with `as`.
|
|
35
|
+
*/
|
|
36
|
+
spread = false;
|
|
37
|
+
/**
|
|
38
|
+
* When true, the runner skips persisting this step's output to state.
|
|
39
|
+
* Only `ctx.prev` carries the result to the immediately next step.
|
|
40
|
+
*/
|
|
41
|
+
ephemeral = false;
|
|
12
42
|
async process(ctx, step) {
|
|
13
43
|
let response = {
|
|
14
44
|
success: true,
|
|
@@ -49,11 +79,21 @@ export default class NodeBase {
|
|
|
49
79
|
runJs(str, ctx, data = {}, func = {}, vars = {}) {
|
|
50
80
|
return Function("ctx", "data", "func", "vars", `"use strict";return (${str});`)(ctx, data, func, vars);
|
|
51
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* @deprecated In v2, return your output and let the runner persist it
|
|
84
|
+
* to `ctx.state[id]` automatically. Use `ctx.publish(name, value)` for
|
|
85
|
+
* explicit side-channel publication when you really need it. This
|
|
86
|
+
* method continues to work for legacy code.
|
|
87
|
+
*/
|
|
52
88
|
setVar(ctx, vars) {
|
|
53
89
|
if (ctx.vars === undefined)
|
|
54
90
|
ctx.vars = {};
|
|
55
91
|
ctx.vars = { ...ctx.vars, ...vars };
|
|
56
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* @deprecated Read from `ctx.state[name]` directly, or reference it from
|
|
95
|
+
* a workflow step's `inputs` as `$.state[name]` / `js/ctx.state.name`.
|
|
96
|
+
*/
|
|
57
97
|
getVar(ctx, name) {
|
|
58
98
|
return ctx.vars?.[name];
|
|
59
99
|
}
|
package/dist/NodeBase.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NodeBase.js","sourceRoot":"","sources":["../src/NodeBase.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,QAAQ,CAAC;AACvB,OAAO,WAAW,MAAM,eAAe,CAAC;AASxC,OAAO,MAAM,MAAM,gBAAgB,CAAC;AAEpC,MAAM,CAAC,OAAO,OAAgB,QAAQ;IAC9B,IAAI,GAAG,KAAK,CAAC;IACb,IAAI,GAAG,EAAE,CAAC;IACV,WAAW,GAAG,EAAE,CAAC;IACjB,MAAM,GAAG,IAAI,CAAC;IACd,IAAI,GAAG,KAAK,CAAC;IACb,cAAc,GAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"NodeBase.js","sourceRoot":"","sources":["../src/NodeBase.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import BlokError, { type BlokErrorOpts, DEFAULT_HTTP_STATUS, DEFAULT_RETRYABLE, ErrorCategory, ErrorSeverity, type NodeErrorPayload } from "./BlokError";
|
|
1
2
|
import GlobalError from "./GlobalError";
|
|
2
3
|
import GlobalLogger from "./GlobalLogger";
|
|
3
4
|
import { Metrics, type MetricsType } from "./Metrics";
|
|
@@ -11,6 +12,8 @@ import LoggerContext from "./types/LoggerContext";
|
|
|
11
12
|
import NodeConfigContext from "./types/NodeConfigContext";
|
|
12
13
|
import RequestContext from "./types/RequestContext";
|
|
13
14
|
import ResponseContext from "./types/ResponseContext";
|
|
15
|
+
import StateContext from "./types/StateContext";
|
|
14
16
|
import Step from "./types/Step";
|
|
17
|
+
import VarsContext from "./types/VarsContext";
|
|
15
18
|
import MemoryUsage from "./utils/MemoryUsage";
|
|
16
|
-
export { NodeBase, Context, RequestContext, ResponseContext, ErrorContext, LoggerContext, ConfigContext, Trigger, NodeConfigContext, FunctionContext, Step, GlobalLogger, GlobalError, Metrics, MemoryUsage, type MetricsType, };
|
|
19
|
+
export { NodeBase, Context, RequestContext, ResponseContext, ErrorContext, LoggerContext, ConfigContext, Trigger, NodeConfigContext, FunctionContext, StateContext, VarsContext, Step, GlobalLogger, GlobalError, BlokError, type BlokErrorOpts, type NodeErrorPayload, ErrorCategory, ErrorSeverity, DEFAULT_HTTP_STATUS, DEFAULT_RETRYABLE, Metrics, MemoryUsage, type MetricsType, };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import BlokError, { DEFAULT_HTTP_STATUS, DEFAULT_RETRYABLE, ErrorCategory, ErrorSeverity, } from "./BlokError";
|
|
1
2
|
import GlobalError from "./GlobalError";
|
|
2
3
|
import GlobalLogger from "./GlobalLogger";
|
|
3
4
|
import { Metrics } from "./Metrics";
|
|
4
5
|
import NodeBase from "./NodeBase";
|
|
5
6
|
import Trigger from "./Trigger";
|
|
6
7
|
import MemoryUsage from "./utils/MemoryUsage";
|
|
7
|
-
export { NodeBase, Trigger, GlobalLogger, GlobalError, Metrics, MemoryUsage, };
|
|
8
|
+
export { NodeBase, Trigger, GlobalLogger, GlobalError, BlokError, ErrorCategory, ErrorSeverity, DEFAULT_HTTP_STATUS, DEFAULT_RETRYABLE, Metrics, MemoryUsage, };
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAoB,MAAM,WAAW,CAAC;AACtD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,OAAO,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,EAAE,EAEjB,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACb,aAAa,GAEb,MAAM,aAAa,CAAC;AACrB,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAoB,MAAM,WAAW,CAAC;AACtD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAClC,OAAO,OAAO,MAAM,WAAW,CAAC;AAYhC,OAAO,WAAW,MAAM,qBAAqB,CAAC;AAE9C,OAAO,EACN,QAAQ,EAOR,OAAO,EAMP,YAAY,EACZ,WAAW,EACX,SAAS,EAGT,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,OAAO,EACP,WAAW,GAEX,CAAC"}
|
package/dist/types/Context.d.ts
CHANGED
|
@@ -6,20 +6,94 @@ import type FunctionContext from "./FunctionContext";
|
|
|
6
6
|
import type LoggerContext from "./LoggerContext";
|
|
7
7
|
import type RequestContext from "./RequestContext";
|
|
8
8
|
import type ResponseContext from "./ResponseContext";
|
|
9
|
+
import type StateContext from "./StateContext";
|
|
9
10
|
import type VarsContext from "./VarsContext";
|
|
11
|
+
/**
|
|
12
|
+
* The runtime context for a single workflow execution. One Context object
|
|
13
|
+
* is created per run and threaded through every step.
|
|
14
|
+
*
|
|
15
|
+
* **The two-tier read model:**
|
|
16
|
+
*
|
|
17
|
+
* - `ctx.prev` — the previous step's full result envelope ({ data, success,
|
|
18
|
+
* error }). Overwritten on every step. Use for adjacent-step access.
|
|
19
|
+
* Aliased by `ctx.response` for back-compat with v1.
|
|
20
|
+
*
|
|
21
|
+
* - `ctx.state[stepId]` — each step's `result.data` is automatically
|
|
22
|
+
* persisted here under the step's `id` (or its `as` override). Use
|
|
23
|
+
* for any-distance access. Aliased by `ctx.vars` for back-compat.
|
|
24
|
+
*
|
|
25
|
+
* **Side-channel publication:**
|
|
26
|
+
*
|
|
27
|
+
* - `ctx.publish(name, value)` — explicitly publish a value into state
|
|
28
|
+
* from inside a node. Logged in Studio's trace tab. Use sparingly —
|
|
29
|
+
* most nodes should just `return` their output and let the runner
|
|
30
|
+
* persist it.
|
|
31
|
+
*
|
|
32
|
+
* **Request envelope aliases:**
|
|
33
|
+
*
|
|
34
|
+
* - `ctx.req` — alias for `ctx.request`. Read query, body, params,
|
|
35
|
+
* headers, etc. via either form.
|
|
36
|
+
*/
|
|
10
37
|
type Context = {
|
|
11
38
|
id: string;
|
|
12
39
|
workflow_name?: string;
|
|
13
40
|
workflow_path?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Request envelope. Body, query, params, headers, etc.
|
|
43
|
+
*
|
|
44
|
+
* Also accessible as `ctx.req` (alias).
|
|
45
|
+
*/
|
|
14
46
|
request: RequestContext;
|
|
47
|
+
/**
|
|
48
|
+
* Alias for `ctx.request` — same object, read-only getter. v2
|
|
49
|
+
* authoring uses `req`; v1 authoring used `request`. Both work.
|
|
50
|
+
*/
|
|
51
|
+
readonly req?: RequestContext;
|
|
52
|
+
/**
|
|
53
|
+
* Previous step's full result envelope. **Overwritten every step.**
|
|
54
|
+
* Use for adjacent-step access only; for cross-step access use
|
|
55
|
+
* `ctx.state[stepId]`.
|
|
56
|
+
*
|
|
57
|
+
* Aliased by `ctx.response` for v1 back-compat.
|
|
58
|
+
*/
|
|
15
59
|
response: ResponseContext;
|
|
60
|
+
/**
|
|
61
|
+
* Alias for `ctx.response` — same object. v2 authoring uses `prev`;
|
|
62
|
+
* v1 authoring used `response.data`. Both work.
|
|
63
|
+
*/
|
|
64
|
+
readonly prev?: ResponseContext;
|
|
16
65
|
error: ErrorContext;
|
|
17
66
|
logger: LoggerContext;
|
|
18
67
|
config: ConfigContext;
|
|
19
68
|
func?: FunctionContext;
|
|
69
|
+
/**
|
|
70
|
+
* Accumulated step outputs by step `id`. Filled automatically when
|
|
71
|
+
* a step completes (unless `ephemeral: true`).
|
|
72
|
+
*
|
|
73
|
+
* Aliased by `ctx.vars` for v1 back-compat — both fields point at
|
|
74
|
+
* the same underlying object.
|
|
75
|
+
*
|
|
76
|
+
* Always initialized to `{}` by `TriggerBase.createContext`. Marked
|
|
77
|
+
* optional only so legacy code paths that hand-construct a Context
|
|
78
|
+
* (some tests, internal utilities) keep type-checking; production
|
|
79
|
+
* runs always have `state` defined.
|
|
80
|
+
*/
|
|
81
|
+
state?: StateContext;
|
|
82
|
+
/**
|
|
83
|
+
* Alias for `ctx.state` — same underlying object. v2 authoring
|
|
84
|
+
* uses `state`; v1 authoring used `vars`. Both work.
|
|
85
|
+
*
|
|
86
|
+
* @deprecated Prefer `ctx.state` (or `$.state.<id>` from inputs).
|
|
87
|
+
*/
|
|
20
88
|
vars?: VarsContext;
|
|
21
89
|
env?: EnvContext;
|
|
22
90
|
eventLogger: GlobalLogger | unknown;
|
|
91
|
+
/**
|
|
92
|
+
* Explicit side-channel publication. Writes to state under `name`
|
|
93
|
+
* and emits a Studio trace event. Use only when a node needs to
|
|
94
|
+
* publish something other than its return value (most nodes don't).
|
|
95
|
+
*/
|
|
96
|
+
publish?: (name: string, value: unknown) => void;
|
|
23
97
|
_PRIVATE_: unknown;
|
|
24
98
|
};
|
|
25
99
|
export default Context;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StateContext — accumulated step outputs for a single workflow run.
|
|
3
|
+
*
|
|
4
|
+
* Every step's `result.data` lands here under the step's `id` (or its
|
|
5
|
+
* `as` override) automatically. Steps marked `ephemeral: true` skip
|
|
6
|
+
* persistence; steps marked `spread: true` shallow-merge their result
|
|
7
|
+
* keys into state.
|
|
8
|
+
*
|
|
9
|
+
* Read via `ctx.state[stepId]` or `$.state[stepId]` from a workflow's
|
|
10
|
+
* `inputs`. Always initialized to `{}` at run start — never undefined.
|
|
11
|
+
*
|
|
12
|
+
* Aliased by `ctx.vars` for backward compatibility with v1 workflows.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ctx.state["fetch-users"] // the data returned by the fetch-users step
|
|
16
|
+
* ctx.state.user // when a step has `as: "user"`
|
|
17
|
+
*/
|
|
18
|
+
type StateContext = {
|
|
19
|
+
[key: string]: unknown;
|
|
20
|
+
};
|
|
21
|
+
export default StateContext;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StateContext.js","sourceRoot":"","sources":["../../src/types/StateContext.ts"],"names":[],"mappings":""}
|
|
@@ -1,5 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* VarsContext — accumulated step outputs for a single workflow run.
|
|
3
|
+
*
|
|
4
|
+
* **Legacy alias for {@link StateContext}.** The two types describe the
|
|
5
|
+
* same underlying object (`ctx.state` and `ctx.vars` are aliases). v2
|
|
6
|
+
* code should prefer `ctx.state` / `StateContext`.
|
|
7
|
+
*
|
|
8
|
+
* Values can be any JSON-serializable shape — a step's output is whatever
|
|
9
|
+
* its node returned. The strict `ParamsDictionary` shape from earlier
|
|
10
|
+
* versions of Blok was inaccurate; real workflows have always stored
|
|
11
|
+
* arbitrary objects, arrays, primitives, etc. here.
|
|
12
|
+
*
|
|
13
|
+
* @deprecated Prefer {@link StateContext}.
|
|
14
|
+
*/
|
|
2
15
|
type VarsContext = {
|
|
3
|
-
[key: string]:
|
|
16
|
+
[key: string]: unknown;
|
|
4
17
|
};
|
|
5
18
|
export default VarsContext;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blokjs/shared",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Shared class, interfaces and types",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,10 +11,7 @@
|
|
|
11
11
|
"test": "vitest run",
|
|
12
12
|
"test:dev": "vitest"
|
|
13
13
|
},
|
|
14
|
-
"keywords": [
|
|
15
|
-
"api",
|
|
16
|
-
"blueprint"
|
|
17
|
-
],
|
|
14
|
+
"keywords": ["api", "blueprint"],
|
|
18
15
|
"author": "Deskree Inc",
|
|
19
16
|
"license": "MIT",
|
|
20
17
|
"devDependencies": {
|