@hydranium/protocol 1.0.0-next.267 → 1.0.0-next.269
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/lib/client/data-connection.d.ts +6 -3
- package/lib/client/data-connection.d.ts.map +1 -1
- package/lib/client/data-connection.js +19 -5
- package/lib/client/data-connection.js.map +1 -1
- package/lib/client/data-session.d.ts +125 -27
- package/lib/client/data-session.d.ts.map +1 -1
- package/lib/client/data-session.js +274 -75
- package/lib/client/data-session.js.map +1 -1
- package/lib/logger.d.ts +5 -5
- package/lib/logger.d.ts.map +1 -1
- package/lib/messages/primitives.d.ts +8 -0
- package/lib/messages/primitives.d.ts.map +1 -1
- package/lib/messages/primitives.js +29 -0
- package/lib/messages/primitives.js.map +1 -1
- package/lib/tracer.d.ts.map +1 -1
- package/lib/tracer.js +2 -1
- package/lib/tracer.js.map +1 -1
- package/package.json +1 -1
- package/src/client/data-connection.ts +21 -6
- package/src/client/data-session.ts +332 -75
- package/src/logger.ts +5 -5
- package/src/messages/primitives.ts +30 -0
- package/src/tracer.ts +2 -1
package/src/logger.ts
CHANGED
|
@@ -39,15 +39,15 @@ let fileLevel: LogThreshold | undefined;
|
|
|
39
39
|
* and every `for` / `sub` / `with` derivation preserves the implementation type.
|
|
40
40
|
*/
|
|
41
41
|
export interface Logger {
|
|
42
|
-
/**
|
|
42
|
+
/** Requested work failed; logged once, by the code that ends the failure, not by one that rethrows it. */
|
|
43
43
|
error(message?: string, ...args: unknown[]): this;
|
|
44
|
-
/**
|
|
44
|
+
/** An anomaly that was handled, or work declined by design, such as a conflict or a cap; a clean run logs none. */
|
|
45
45
|
warn(message?: string, ...args: unknown[]): this;
|
|
46
|
-
/**
|
|
46
|
+
/** A milestone the person running the server would recognise without knowing the internals. */
|
|
47
47
|
info(message?: string, ...args: unknown[]): this;
|
|
48
|
-
/**
|
|
48
|
+
/** Diagnosis; its level decides whether the line is built, never which code runs. */
|
|
49
49
|
debug(message?: string, ...args: unknown[]): this;
|
|
50
|
-
/** High-volume
|
|
50
|
+
/** High-volume diagnosis, emitted only at the `'trace'` threshold; as for `debug`, no code runs only for it. */
|
|
51
51
|
trace(message?: string, ...args: unknown[]): this;
|
|
52
52
|
/** Log a message at info-level threshold with a `Log` label (rather than `Info`). */
|
|
53
53
|
log(message?: string, ...args: unknown[]): this;
|
|
@@ -236,11 +236,41 @@ export function resolvedFromResponseError(error: ResponseError<unknown>): Resolv
|
|
|
236
236
|
* to pass as a parameter for the same reason a number is: it is not itself
|
|
237
237
|
* translatable text, so it needs no code of its own. A PROSE fragment is not,
|
|
238
238
|
* and must become one code per value instead.
|
|
239
|
+
*
|
|
240
|
+
* For a reader of the client; the log takes {@link describeErrorWithStack}.
|
|
239
241
|
*/
|
|
240
242
|
export function describeError(error: unknown): string {
|
|
241
243
|
return error instanceof Error ? error.message : String(error);
|
|
242
244
|
}
|
|
243
245
|
|
|
246
|
+
/**
|
|
247
|
+
* An error for the log: its stack where it has one, which names where it was
|
|
248
|
+
* thrown, and its causes, which name what failed when an error wraps another.
|
|
249
|
+
* Never for the client, whose reader cannot act on a stack.
|
|
250
|
+
*/
|
|
251
|
+
export function describeErrorWithStack(error: unknown): string {
|
|
252
|
+
// A cause chain may loop back on itself.
|
|
253
|
+
return describeChain(error, new Set());
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function describeChain(error: unknown, seen: Set<unknown>): string {
|
|
257
|
+
const lines: string[] = [];
|
|
258
|
+
let current: unknown = error;
|
|
259
|
+
let prefix = '';
|
|
260
|
+
do {
|
|
261
|
+
seen.add(current);
|
|
262
|
+
lines.push(prefix + (current instanceof Error ? (current.stack ?? current.message) : String(current)));
|
|
263
|
+
// Node fails a connect to several addresses with one, whose own message is empty.
|
|
264
|
+
if (current instanceof AggregateError) {
|
|
265
|
+
const errors: unknown[] = current.errors;
|
|
266
|
+
lines.push(...errors.filter(inner => !seen.has(inner)).map(inner => `Including: ${describeChain(inner, seen)}`));
|
|
267
|
+
}
|
|
268
|
+
current = current instanceof Error ? current.cause : undefined;
|
|
269
|
+
prefix = 'Caused by: ';
|
|
270
|
+
} while (current !== undefined && current !== null && !seen.has(current));
|
|
271
|
+
return lines.join('\n');
|
|
272
|
+
}
|
|
273
|
+
|
|
244
274
|
/**
|
|
245
275
|
* Recognises a declaration among a barrel's exports. The `format` check is what
|
|
246
276
|
* discriminates: a `code` + `text` pair alone admits any object that happens to
|
package/src/tracer.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { Format, Logger, type LogThreshold } from './logger';
|
|
|
12
12
|
import { NoopLogger } from './noop-logger';
|
|
13
13
|
import { DefaultProfileSession, type ProfileSession } from './profile-session';
|
|
14
14
|
import { Disposable } from './util';
|
|
15
|
+
import { describeErrorWithStack } from './messages/primitives';
|
|
15
16
|
|
|
16
17
|
/** Module-global so nested timers don't reuse ids. */
|
|
17
18
|
let nextTimerId = 0;
|
|
@@ -183,7 +184,7 @@ export class DefaultTracer implements Tracer {
|
|
|
183
184
|
if (status === 'failed') {
|
|
184
185
|
// Reporting the failure is the caller's, who receives it: a line at
|
|
185
186
|
// warn here would exist only while `logLevel` is enabled.
|
|
186
|
-
const detail =
|
|
187
|
+
const detail = describeErrorWithStack(error);
|
|
187
188
|
this.logger.debug(`${label} [#${id}] failed: ${detail}`);
|
|
188
189
|
}
|
|
189
190
|
};
|