authorgravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-06-15 12:58:06-07:00
committergravatar for git@paperclover.netclover caruso <git@paperclover.net> 2026-06-15 13:02:24-07:00
logcedba8ef7133a2d55f9c5318b0e6098ab0fe4abd
tree42bf64c9720ccf837b62bf4647cc1862e0f8c950
parenta25086ee5de025766806d480542ed6c10aef35f9
signature Signed by SSH key SHA256:cOKiuRFOeSRxne6EWgHtdQQSlBxjOXm2hOCFnCdLQbQ

chore: rename lib module `error` to `exception`

found this was better namespace name while working on incremental. closes #105

10 files changed, 72 insertions(+), 72 deletions(-)

framework/font.ts+3-3
......@@ -97,7 +97,7 @@ async function fetchProductionFontFiles(
9797 throw new Error(`Fetching fallback from ${url} failed: ${response.status} ${response.statusText}`);
9898 }
9999 } catch (err) {
100 throw new Error(`Fetching fallback from ${url} failed: ${error.message(err)}`);
100 throw new Error(`Fetching fallback from ${url} failed: ${exception.message(err)}`);
101101 }
102102 }
103103
......@@ -137,7 +137,7 @@ export async function fetchFont(ref: progress.Ref, name: string, sources: string
137137 continue;
138138 }
139139 } catch (err) {
140 errs.push(`Fetching from ${source} failed: ${error.message(err)}`);
140 errs.push(`Fetching from ${source} failed: ${exception.message(err)}`);
141141 continue;
142142 }
143143 }
......@@ -386,7 +386,7 @@ import * as sg from "#sitegen";
386386import * as fs from "#sitegen/fs";
387387import { ASSERT } from "@clo/lib/assert";
388388import * as async from "@clo/lib/async";
389import * as error from "@clo/lib/error";
389import * as exception from "@clo/lib/exception";
390390import * as progress from "@clo/lib/progress";
391391import * as queue from "@clo/lib/queue";
392392import { readFile } from "node:fs/promises";
framework/generate.ts+2-2
......@@ -362,7 +362,7 @@ export async function preparePage(
362362 clientRefs: Array.from(cloverScripts),
363363 } as const;
364364 } catch (e) {
365 error.rethrowWithMetadata(e, { page: item.id });
365 exception.rethrowWithMetadata(e, { page: item.id });
366366 }
367367}
368368
......@@ -456,7 +456,7 @@ import * as path from "node:path";
456456import * as sg from "#sitegen";
457457import type { FileItem } from "#sitegen";
458458import * as fs from "#sitegen/fs";
459import * as error from "@clo/lib/error";
459import * as exception from "@clo/lib/exception";
460460import * as meta from "@clo/lib/meta";
461461import * as progress from "@clo/lib/progress";
462462
framework/lib/path.ts+3-3
......@@ -131,7 +131,7 @@ export class Path {
131131 try {
132132 return this.readSync(encoding);
133133 } catch (err) {
134 if (error.code(err) === "ENOENT") return null;
134 if (exception.code(err) === "ENOENT") return null;
135135 throw err;
136136 }
137137 }
......@@ -159,7 +159,7 @@ export class Path {
159159 try {
160160 return await this.read(encoding);
161161 } catch (err) {
162 if (error.code(err) === "ENOENT") return null;
162 if (exception.code(err) === "ENOENT") return null;
163163 throw err;
164164 }
165165 }
......@@ -209,7 +209,7 @@ export class Path {
209209}
210210
211211import { ASSERT } from "@clo/lib/assert";
212import * as error from "@clo/lib/error";
212import * as exception from "@clo/lib/exception";
213213import type { RmOptions } from "node:fs";
214214import * as path from "node:path";
215215import * as util from "node:util";
lib/error.ts deleted-53
......@@ -1,53 +0,0 @@
1/**
2 * helper functions for dealing with the `unknown` type, mainly in `catch`
3 * blocks or promise rejection callbacks.
4 *
5 * @module
6 */
7
8/** extra fields on errors are extremely helpful for debugging. */
9export interface Error extends globalThis.Error {
10 [metadata: string]: unknown;
11}
12
13/** retrieve an error message from any value */
14export function message(error: unknown): string {
15 let message = (error as { message: unknown })?.message ?? error;
16 try {
17 message = typeof message === "string"
18 ? message
19 // NOTE: typescript standard library lies here (https://github.com/mattpocock/ts-reset/pull/190)
20 : String(JSON.stringify(message) as string | undefined);
21 } catch {}
22 try {
23 return String(message);
24 } catch {}
25 return `Could not stringify error message ${typeof message}`;
26}
27
28/** retrieve an error-like object from any value. Useful to check fields. */
29export function obj(error: unknown): { message: string } & Partial<Error> {
30 if (error instanceof Error) return error as Error;
31 return {
32 message: message(error),
33 ...(typeof error === "object" && error),
34 };
35}
36
37/** node.js error codes are string values on the `.code` property. */
38export function code(error: unknown): node.ErrorCode | null {
39 const code = (error as { code: unknown })?.code;
40 return typeof code === "string" ? code : null;
41}
42
43/** attach extra fields and rethrow a value. */
44export function rethrowWithMetadata(
45 err: unknown,
46 meta: Record<string, unknown>,
47): never {
48 const error = err && typeof err === "object" ? err : new Error(message(err)); // no stack trace :/
49 Object.assign(error, meta);
50 throw error;
51}
52
53import type * as node from "./node.ts";
lib/exception.ts created+53
......@@ -0,0 +1,53 @@
1/**
2 * helper functions for dealing with the `unknown` type, mainly in `catch`
3 * blocks or promise rejection callbacks.
4 *
5 * @module
6 */
7
8/** extra fields on errors are extremely helpful for debugging. */
9export interface Error extends globalThis.Error {
10 [metadata: string]: unknown;
11}
12
13/** retrieve an error message from any value */
14export function message(error: unknown): string {
15 let message = (error as { message: unknown })?.message ?? error;
16 try {
17 message = typeof message === "string"
18 ? message
19 // NOTE: typescript standard library lies here (https://github.com/mattpocock/ts-reset/pull/190)
20 : String(JSON.stringify(message) as string | undefined);
21 } catch {}
22 try {
23 return String(message);
24 } catch {}
25 return `Could not stringify error message ${typeof message}`;
26}
27
28/** retrieve an error-like object from any value. Useful to check fields. */
29export function obj(error: unknown): { message: string } & Partial<Error> {
30 if (error instanceof Error) return error as Error;
31 return {
32 message: message(error),
33 ...(typeof error === "object" && error),
34 };
35}
36
37/** node.js error codes are string values on the `.code` property. */
38export function code(error: unknown): node.ErrorCode | null {
39 const code = (error as { code: unknown })?.code;
40 return typeof code === "string" ? code : null;
41}
42
43/** attach extra fields and rethrow a value. */
44export function rethrowWithMetadata(
45 err: unknown,
46 meta: Record<string, unknown>,
47): never {
48 const error = err && typeof err === "object" ? err : new Error(message(err)); // no stack trace :/
49 Object.assign(error, meta);
50 throw error;
51}
52
53import type * as node from "./node.ts";
lib/http.ts+2-2
......@@ -82,7 +82,7 @@ export async function serve(
8282
8383 const actualPort = await new Promise<number>((resolve, reject) => {
8484 async function onError(err: unknown) {
85 if (error.code(err) !== "EADDRINUSE") {
85 if (exception.code(err) !== "EADDRINUSE") {
8686 reject(err);
8787 return;
8888 }
......@@ -168,7 +168,7 @@ export interface Range {
168168import * as nodeHttp from "node:http";
169169import * as stream from "node:stream";
170170import { ASSERT, UNWRAP } from "./assert.ts";
171import * as error from "./error.ts";
171import * as exception from "./exception.ts";
172172import * as node from "./node.ts";
173173import * as progress from "./progress.ts";
174174import * as subprocess from "./subprocess.ts";
lib/log.ts+2-2
......@@ -603,7 +603,7 @@ export function createTerminalWidgetHost(
603603 height: rows,
604604 });
605605 } catch (e) {
606 out = e instanceof Error ? stack.format(e, color) : errors.message(e);
606 out = e instanceof Error ? stack.format(e, color) : exceptions.message(e);
607607 }
608608 if (out == null) {
609609 widgets.splice(w, 1);
......@@ -1509,7 +1509,7 @@ export type MessageFormatFunction = (
15091509
15101510import { ASSERT, UNWRAP } from "./assert.ts";
15111511import * as async from "./async.ts";
1512import * as errors from "./error.ts";
1512import * as exceptions from "./exception.ts";
15131513import * as stack from "./log/stack.ts";
15141514import * as node from "./node.ts";
15151515import * as ansi from "./string/ansi.ts";
lib/progress.ts+2-2
......@@ -987,7 +987,7 @@ export function encodeEventStream<
987987 emitNow();
988988 }));
989989 stack.use(root.on("error", (error) => {
990 s.pendingEvents.push(["error", errors.message(error)]);
990 s.pendingEvents.push(["error", exceptions.message(error)]);
991991 s.ended = true;
992992 emitNow();
993993 }));
......@@ -1857,7 +1857,7 @@ export const internals: {
18571857import { ASSERT, UNWRAP } from "./assert.ts";
18581858import * as async from "./async.ts";
18591859import * as bytes from "./bytes.ts";
1860import * as errors from "./error.ts";
1860import * as exceptions from "./exception.ts";
18611861import { Events } from "./Events.ts";
18621862import * as log from "./log.ts";
18631863import * as stack from "./log/stack.ts";
src/file-viewer/cache.ts+2-2
......@@ -127,7 +127,7 @@ export async function read(
127127 try {
128128 ({ size } = await localFile.stat());
129129 } catch (err) {
130 if (error.code(err) === "ENOENT") {
130 if (exception.code(err) === "ENOENT") {
131131 console.warn(`missing local file: ${localFile}`);
132132 break local;
133133 }
......@@ -598,7 +598,7 @@ import * as fs from "#sitegen/fs";
598598import { Path } from "#sitegen/path";
599599import { ASSERT, UNWRAP } from "@clo/lib/assert";
600600import * as async from "@clo/lib/async";
601import * as error from "@clo/lib/error";
601import * as exception from "@clo/lib/exception";
602602import * as log from "@clo/lib/log";
603603import { Lru } from "@clo/lib/Lru";
604604import * as ts from "@clo/lib/ts";
src/file-viewer/indexer/scan.ts+3-3
......@@ -125,7 +125,7 @@ export class Scanner {
125125 try {
126126 stat = await path.stat();
127127 } catch (err) {
128 if (error.code(err) !== "ENOENT") throw err;
128 if (exception.code(err) !== "ENOENT") throw err;
129129 // deleted; watcher events often describe files already gone
130130 this.#removePath(publicPath);
131131 return;
......@@ -308,7 +308,7 @@ export class Scanner {
308308 try {
309309 stat = await path.stat();
310310 } catch (err) {
311 if (error.code(err) === "ENOENT") return null;
311 if (exception.code(err) === "ENOENT") return null;
312312 throw err;
313313 }
314314 }
......@@ -546,7 +546,7 @@ import * as path from "node:path";
546546import { Path } from "#sitegen/path";
547547import { ASSERT, UNWRAP } from "@clo/lib/assert";
548548import * as async from "@clo/lib/async";
549import * as error from "@clo/lib/error";
549import * as exception from "@clo/lib/exception";
550550import * as log from "@clo/lib/log";
551551import * as progress from "@clo/lib/progress";
552552import * as queue from "@clo/lib/queue";