@oh-my-pi/pi-utils 18.0.8 → 18.0.9
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/CHANGELOG.md +6 -0
- package/dist/types/postmortem.d.ts +4 -4
- package/package.json +2 -2
- package/src/postmortem.ts +18 -11
package/CHANGELOG.md
CHANGED
|
@@ -107,10 +107,10 @@ export declare function registerStdioDisconnectHandling(): () => void;
|
|
|
107
107
|
*/
|
|
108
108
|
export declare function markExpectedCleanupError<T extends object>(reason: T): T;
|
|
109
109
|
/**
|
|
110
|
-
* Whether `reason` (or any
|
|
111
|
-
* {@link markExpectedCleanupError}.
|
|
112
|
-
*
|
|
113
|
-
*
|
|
110
|
+
* Whether `reason` (or any object in its bounded `cause` chain) was explicitly
|
|
111
|
+
* marked via {@link markExpectedCleanupError}. Runtime error names and codes
|
|
112
|
+
* are intentionally insufficient: unmarked `AbortError` and socket failures
|
|
113
|
+
* can originate from application code and must remain fatal when unhandled.
|
|
114
114
|
*/
|
|
115
115
|
export declare function isExpectedCleanupError(reason: unknown): boolean;
|
|
116
116
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-utils",
|
|
4
|
-
"version": "18.0.
|
|
4
|
+
"version": "18.0.9",
|
|
5
5
|
"description": "Shared utilities for pi packages",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Stencil Labs, Inc.",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"fmt": "biome format --write ."
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@oh-my-pi/pi-natives": "18.0.
|
|
34
|
+
"@oh-my-pi/pi-natives": "18.0.9"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/bun": "^1.3.14"
|
package/src/postmortem.ts
CHANGED
|
@@ -263,25 +263,29 @@ const EXPECTED_CLEANUP = Symbol.for("omp.expectedCleanupError");
|
|
|
263
263
|
* consumer. Returns the same error for inline use at the `abort()` callsite.
|
|
264
264
|
*/
|
|
265
265
|
export function markExpectedCleanupError<T extends object>(reason: T): T {
|
|
266
|
-
(reason
|
|
266
|
+
Reflect.set(reason, EXPECTED_CLEANUP, true);
|
|
267
267
|
return reason;
|
|
268
268
|
}
|
|
269
269
|
|
|
270
|
-
|
|
271
|
-
* Whether `reason` (or any error in its `cause` chain) was marked via
|
|
272
|
-
* {@link markExpectedCleanupError}. Walks the chain because the unhandled
|
|
273
|
-
* reason is often a wrapper (`AbortError`) with the marked abort reason as
|
|
274
|
-
* its `cause`.
|
|
275
|
-
*/
|
|
276
|
-
export function isExpectedCleanupError(reason: unknown): boolean {
|
|
270
|
+
function hasExpectedCleanupMarker(reason: unknown): boolean {
|
|
277
271
|
let current: unknown = reason;
|
|
278
272
|
for (let depth = 0; depth < 8 && current !== null && typeof current === "object"; depth++) {
|
|
279
|
-
if ((current
|
|
280
|
-
current = (current
|
|
273
|
+
if (Reflect.get(current, EXPECTED_CLEANUP) === true) return true;
|
|
274
|
+
current = Reflect.get(current, "cause");
|
|
281
275
|
}
|
|
282
276
|
return false;
|
|
283
277
|
}
|
|
284
278
|
|
|
279
|
+
/**
|
|
280
|
+
* Whether `reason` (or any object in its bounded `cause` chain) was explicitly
|
|
281
|
+
* marked via {@link markExpectedCleanupError}. Runtime error names and codes
|
|
282
|
+
* are intentionally insufficient: unmarked `AbortError` and socket failures
|
|
283
|
+
* can originate from application code and must remain fatal when unhandled.
|
|
284
|
+
*/
|
|
285
|
+
export function isExpectedCleanupError(reason: unknown): boolean {
|
|
286
|
+
return hasExpectedCleanupMarker(reason);
|
|
287
|
+
}
|
|
288
|
+
|
|
285
289
|
/** Interceptors consulted by the global `unhandledRejection` handler before the fatal path. */
|
|
286
290
|
const rejectionInterceptors = new Set<(reason: unknown) => boolean>();
|
|
287
291
|
|
|
@@ -366,7 +370,10 @@ if (isMainThread) {
|
|
|
366
370
|
process.stderr.write(`Inspector opened: ${url}\n`);
|
|
367
371
|
})
|
|
368
372
|
.on("uncaughtException", async thrown => {
|
|
369
|
-
|
|
373
|
+
// Only explicitly marked exceptions are safe here. Structural
|
|
374
|
+
// AbortError/socket classification is limited to promise rejections:
|
|
375
|
+
// a synchronously thrown error may indicate an application bug.
|
|
376
|
+
if (hasExpectedCleanupMarker(thrown)) {
|
|
370
377
|
logger.warn("Ignoring expected cleanup exception", { err: thrown });
|
|
371
378
|
return;
|
|
372
379
|
}
|