@jskit-ai/kernel 0.1.118 → 0.1.119
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/package.json
CHANGED
|
@@ -22,6 +22,19 @@ function nowMilliseconds() {
|
|
|
22
22
|
return Date.now();
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
function createProviderLifecycleError(providerId, phase, cause) {
|
|
26
|
+
const message = `Provider \"${providerId}\" failed during ${phase}().`;
|
|
27
|
+
const causeMessage = String(cause?.message || cause || "").trim();
|
|
28
|
+
return new ProviderLifecycleError(
|
|
29
|
+
causeMessage ? `${message} ${causeMessage}` : message,
|
|
30
|
+
{
|
|
31
|
+
providerId,
|
|
32
|
+
phase,
|
|
33
|
+
cause
|
|
34
|
+
}
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
25
38
|
class Application {
|
|
26
39
|
constructor({ profile = "", strict = true, container = null } = {}) {
|
|
27
40
|
this.profile = normalizeText(profile);
|
|
@@ -196,11 +209,7 @@ class Application {
|
|
|
196
209
|
await entry.provider.register(this);
|
|
197
210
|
}
|
|
198
211
|
} catch (error) {
|
|
199
|
-
throw
|
|
200
|
-
providerId: entry.id,
|
|
201
|
-
phase: "register",
|
|
202
|
-
cause: error
|
|
203
|
-
});
|
|
212
|
+
throw createProviderLifecycleError(entry.id, "register", error);
|
|
204
213
|
} finally {
|
|
205
214
|
this.diagnostics.timings.register[entry.id] = nowMilliseconds() - startedAt;
|
|
206
215
|
}
|
|
@@ -222,11 +231,7 @@ class Application {
|
|
|
222
231
|
await entry.provider.boot(this);
|
|
223
232
|
}
|
|
224
233
|
} catch (error) {
|
|
225
|
-
throw
|
|
226
|
-
providerId: entry.id,
|
|
227
|
-
phase: "boot",
|
|
228
|
-
cause: error
|
|
229
|
-
});
|
|
234
|
+
throw createProviderLifecycleError(entry.id, "boot", error);
|
|
230
235
|
} finally {
|
|
231
236
|
this.diagnostics.timings.boot[entry.id] = nowMilliseconds() - startedAt;
|
|
232
237
|
}
|
|
@@ -255,11 +260,7 @@ class Application {
|
|
|
255
260
|
await entry.provider.shutdown(this);
|
|
256
261
|
}
|
|
257
262
|
} catch (error) {
|
|
258
|
-
throw
|
|
259
|
-
providerId: entry.id,
|
|
260
|
-
phase: "shutdown",
|
|
261
|
-
cause: error
|
|
262
|
-
});
|
|
263
|
+
throw createProviderLifecycleError(entry.id, "shutdown", error);
|
|
263
264
|
} finally {
|
|
264
265
|
this.diagnostics.timings.shutdown[entry.id] = nowMilliseconds() - startedAt;
|
|
265
266
|
}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import path from "node:path";
|
|
3
6
|
import process from "node:process";
|
|
4
7
|
import test from "node:test";
|
|
5
8
|
import { fileURLToPath } from "node:url";
|
|
@@ -19,30 +22,35 @@ test("KernelError preserves structured details while exposing the standard cause
|
|
|
19
22
|
assert.equal(error.details.providerId, "example.provider");
|
|
20
23
|
});
|
|
21
24
|
|
|
22
|
-
test("provider lifecycle failures expose their
|
|
25
|
+
test("provider lifecycle failures expose their cause in Node test output", async (context) => {
|
|
26
|
+
const fixtureRoot = await mkdtemp(path.join(tmpdir(), "jskit-kernel-error-"));
|
|
27
|
+
context.after(() => rm(fixtureRoot, { recursive: true, force: true }));
|
|
28
|
+
const fixturePath = path.join(fixtureRoot, "provider-lifecycle-failure.test.mjs");
|
|
23
29
|
const source = `
|
|
24
30
|
import { Application } from ${JSON.stringify(APPLICATION_PATH)};
|
|
31
|
+
import test from "node:test";
|
|
25
32
|
|
|
26
|
-
|
|
27
|
-
app
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
try {
|
|
33
|
+
test("generated server starts", async () => {
|
|
34
|
+
const app = new Application();
|
|
35
|
+
app.configureProviders([{
|
|
36
|
+
id: "json-rest-api.core",
|
|
37
|
+
async boot() {
|
|
38
|
+
throw new Error("DB_CLIENT is required. Use mysql2 or pg.");
|
|
39
|
+
}
|
|
40
|
+
}]);
|
|
35
41
|
await app.bootProviders();
|
|
36
|
-
}
|
|
37
|
-
console.error("Failed to start generated server:", error);
|
|
38
|
-
}
|
|
42
|
+
});
|
|
39
43
|
`;
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
await writeFile(fixturePath, source, "utf8");
|
|
45
|
+
const childEnvironment = { ...process.env };
|
|
46
|
+
delete childEnvironment.NODE_TEST_CONTEXT;
|
|
47
|
+
const result = spawnSync(process.execPath, ["--test", fixturePath], {
|
|
48
|
+
encoding: "utf8",
|
|
49
|
+
env: childEnvironment
|
|
42
50
|
});
|
|
51
|
+
const output = `${String(result.stdout || "")}\n${String(result.stderr || "")}`;
|
|
43
52
|
|
|
44
|
-
assert.equal(result.status,
|
|
45
|
-
assert.match(
|
|
46
|
-
assert.match(
|
|
47
|
-
assert.match(result.stderr, /DB_CLIENT is required\. Use mysql2 or pg\./u);
|
|
53
|
+
assert.equal(result.status, 1, output);
|
|
54
|
+
assert.match(output, /Provider "json-rest-api\.core" failed during boot\(\)\./u);
|
|
55
|
+
assert.match(output, /DB_CLIENT is required\. Use mysql2 or pg\./u);
|
|
48
56
|
});
|