Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/ses/src/error/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ export const sanitizeError = error => {
errors: _errorsDesc = undefined,
cause: _causeDesc = undefined,
stack: _stackDesc = undefined,
code: _codeDesc = undefined,
...restDescs
} = descs;

Expand Down Expand Up @@ -345,6 +346,7 @@ const makeError = (
cause = undefined,
errors = undefined,
sanitize = true,
code = undefined,
} = {},
) => {
// Promote string-valued `optDetails` into a minimal DetailsParts
Expand Down Expand Up @@ -378,6 +380,14 @@ const makeError = (
});
}
}
if (code !== undefined && typeof code === 'string') {
Copy link
Contributor

@erights erights Mar 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here, there's no good answer for "what do to if code is not a string?". Rather, I think that here, following the proposal, you should not filter by the value of code. Rather, put this value test above in sanitizeError. There, if you see a non-string code, delete it and add it to droppedDetails so that it is hidden but shows up as a diagnostic on console output.

defineProperty(error, 'code', {
value: code,
writable: true,
enumerable: false,
configurable: true,
});
}
weakmapSet(hiddenMessageLogArgs, error, getLogArgs(hiddenDetails));
if (errorName !== undefined) {
tagError(error, errorName);
Expand Down
7 changes: 7 additions & 0 deletions packages/ses/test/error/assert-log.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,13 @@ test('makeError named', t => {
);
});

test('makeError code', t => {
const err = makeError(X`<${'bar'},${q('baz')}>`, URIError, {
code: 'FOO_ERR',
});
t.is(err.code, 'FOO_ERR');
});

test('assert.quote', t => {
throwsAndLogs(t, () => Fail`<${'bar'},${q('baz')}>`, /<\(a string\),"baz">/, [
['log', 'Caught', Error],
Expand Down
16 changes: 13 additions & 3 deletions packages/ses/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ export interface AssertMakeErrorOptions {
* {@link sanitizeError}.
*/
sanitize?: boolean;

/**
* The error code to assign to the error.
*/
code?: string;
}

// TODO inline overloading
Expand Down Expand Up @@ -305,14 +310,19 @@ export type GenericErrorConstructor =
| ErrorConstructor
| AggregateErrorConstructor;

/**
* An `Error` with a `code` property.
*/
export type CodableError = Error & { code?: string };

/**
* To make an `assert` which terminates some larger unit of computation
* like a transaction, vat, or process, call `makeAssert` with a `Raise`
* callback, where that callback actually performs that larger termination.
* If possible, the callback should also report its `reason` parameter as
* the alleged reason for the termination.
*/
export type Raise = (reason: Error) => void;
export type Raise = (reason: CodableError) => void;

/**
* Makes and returns an `assert` function object that shares the
Expand Down Expand Up @@ -396,13 +406,13 @@ export interface AssertionUtilities {
/** An optional alternate error constructor to use */
errConstructor?: GenericErrorConstructor,
options?: AssertMakeErrorOptions,
): Error;
): CodableError;

/**
* Associate `details` with `error`, potentially to be logged by an associated
* console for providing extra information about the error.
*/
note(error: Error, details: Details): void;
note(error: CodableError, details: Details): void;

/**
* Use as a template literal tag to create an opaque {@link DetailsToken} for
Expand Down
8 changes: 4 additions & 4 deletions packages/ses/types.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable @endo/no-polymorphic-call, import/no-extraneous-dependencies, no-restricted-globals, no-underscore-dangle */
import { expectType } from 'tsd';
import type { Assert } from 'ses';
import type { Assert, CodableError } from 'ses';

// Lockdown

Expand Down Expand Up @@ -214,11 +214,11 @@ X`canst thou string?`.toString();

const stringable = q(null);

expectType<Error>(makeError(X`details are ${q(stringable)}`));
expectType<CodableError>(makeError(X`details are ${q(stringable)}`));

expectType<Error>(makeError(X`details are ${stringable}`, TypeError));
expectType<CodableError>(makeError(X`details are ${stringable}`, TypeError));

expectType<Error>(
expectType<CodableError>(
makeError(X`details are ${stringable}`, TypeError, {
errorName: 'Nom de plum',
}),
Expand Down
Loading