@dxos/errors 0.8.4-main.67995b8 → 0.8.4-main.a4bbb77

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/errors",
3
- "version": "0.8.4-main.67995b8",
3
+ "version": "0.8.4-main.a4bbb77",
4
4
  "description": "Error definitions",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,10 +10,10 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
- "node": "./dist/lib/node-esm/index.mjs",
16
- "source": "./src/index.ts"
16
+ "node": "./dist/lib/node-esm/index.mjs"
17
17
  }
18
18
  },
19
19
  "types": "dist/types/src/index.d.ts",
package/src/base.ts CHANGED
@@ -2,12 +2,14 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- export type BaseErrorOptions = {
5
+ /**
6
+ * Options for creating a BaseError.
7
+ */
8
+ export type BaseErrorOptions = ErrorOptions & {
6
9
  /**
7
- * The cause of the error.
8
- * An instance of Error.
10
+ * Override base message.
9
11
  */
10
- cause?: unknown;
12
+ message?: string;
11
13
 
12
14
  /**
13
15
  * Structured details about the error.
@@ -21,14 +23,11 @@ export type BaseErrorOptions = {
21
23
  export class BaseError<Code extends string = string> extends Error {
22
24
  /**
23
25
  * Primary way of defining new error classes.
24
- *
25
- * Expample:
26
- *
27
- * ```ts
28
- * export class AiInputPreprocessingError extends BaseError.extend('AI_INPUT_PREPROCESSING_ERROR') {}
29
- * ```
26
+ * Extended class may specialize constructor for required context params.
27
+ * @param code - Error code.
28
+ * @param message - Default error message.
30
29
  */
31
- static extend<Code extends string>(code: Code) {
30
+ static extend<Code extends string = string>(code: Code, message?: string) {
32
31
  return class extends BaseError<Code> {
33
32
  static code = code;
34
33
 
@@ -36,12 +35,12 @@ export class BaseError<Code extends string = string> extends Error {
36
35
  return typeof error === 'object' && error !== null && 'code' in error && error.code === code;
37
36
  }
38
37
 
39
- static wrap(message: string, options?: Omit<BaseErrorOptions, 'cause'>) {
40
- return (error: unknown) => new this(message, { ...options, cause: error });
38
+ static wrap(options?: Omit<BaseErrorOptions, 'cause'>) {
39
+ return (error: unknown) => new this({ message, ...options, cause: error });
41
40
  }
42
41
 
43
- constructor(message: string, options?: BaseErrorOptions) {
44
- super(code, message, options);
42
+ constructor(options?: BaseErrorOptions) {
43
+ super(code, { message: options?.message ?? message, ...options });
45
44
  }
46
45
  };
47
46
  }
@@ -49,8 +48,8 @@ export class BaseError<Code extends string = string> extends Error {
49
48
  #code: Code;
50
49
  #context: Record<string, unknown>;
51
50
 
52
- constructor(code: Code, message: string, options?: BaseErrorOptions) {
53
- super(message, options);
51
+ constructor(code: Code, options?: BaseErrorOptions) {
52
+ super(options?.message, { cause: options?.cause });
54
53
 
55
54
  this.#code = code;
56
55
  this.#context = options?.context ?? {};
@@ -61,6 +60,11 @@ export class BaseError<Code extends string = string> extends Error {
61
60
  return this.#code;
62
61
  }
63
62
 
63
+ /** Fallback message. */
64
+ override get message() {
65
+ return this.constructor.name;
66
+ }
67
+
64
68
  get code(): Code {
65
69
  return this.#code;
66
70
  }
@@ -4,11 +4,12 @@
4
4
 
5
5
  import { describe, expect, test } from 'vitest';
6
6
 
7
+ import { BaseError, type BaseErrorOptions } from './base';
7
8
  import { SystemError } from './errors';
8
9
 
9
10
  describe('errors', () => {
10
11
  test('error code and message, cause', () => {
11
- const error = new SystemError('Test message', { cause: new Error('Test cause'), context: { a: 1, b: 2 } });
12
+ const error = new SystemError({ message: 'Test message', cause: new Error('Test cause'), context: { a: 1, b: 2 } });
12
13
  expect(error).toBeInstanceOf(SystemError);
13
14
  expect(error).toBeInstanceOf(SystemError);
14
15
  expect(error.code).toBe(SystemError.code);
@@ -24,19 +25,37 @@ describe('errors', () => {
24
25
  expect.fail('Expected error to be thrown');
25
26
  } catch (error: any) {
26
27
  expect(error).toBeInstanceOf(SystemError);
27
- expect(String(error)).toEqual('SYSTEM_ERROR: Test message');
28
+ expect(String(error)).toEqual('SYSTEM: Test message');
28
29
  const stackLines = error.stack!.split('\n');
29
- expect(stackLines?.[0]).toEqual('SYSTEM_ERROR: Test message');
30
+ expect(stackLines?.[0]).toEqual('SYSTEM: Test message');
30
31
  expect(stackLines?.[1]).toMatch(/^ {4}at two \(.*$/);
31
32
  expect(stackLines?.[2]).toMatch(/^ {4}at one \(.*$/);
32
33
  }
33
34
  });
35
+
36
+ test('custom message', () => {
37
+ class CustomError extends BaseError.extend('CUSTOM', 'Custom message') {
38
+ constructor(value: number, options?: Omit<BaseErrorOptions, 'context'>) {
39
+ super({ context: { value }, ...options });
40
+ }
41
+ }
42
+
43
+ const error = new CustomError(1);
44
+ expect(error).toBeInstanceOf(CustomError);
45
+ expect(error.message).toBe('Custom message');
46
+ expect(error.context).toEqual({ value: 1 });
47
+ });
48
+
49
+ test('is', () => {
50
+ const error = new SystemError({ message: 'Test message' });
51
+ expect(SystemError.is(error)).toBe(true);
52
+ });
34
53
  });
35
54
 
36
55
  const throwError = () => {
37
56
  const one = () => {
38
57
  const two = () => {
39
- throw new SystemError('Test message');
58
+ throw new SystemError({ message: 'Test message' });
40
59
  };
41
60
  two();
42
61
  };
package/src/errors.ts CHANGED
@@ -4,14 +4,14 @@
4
4
 
5
5
  import { BaseError } from './base';
6
6
 
7
- export class TimeoutError extends BaseError.extend('TIMEOUT') {}
7
+ export class ApiError extends BaseError.extend('API', 'API error') {}
8
8
 
9
- export class AbortedError extends BaseError.extend('ABORTED') {}
9
+ export class SystemError extends BaseError.extend('SYSTEM', 'System error') {}
10
10
 
11
- export class UnimplementedError extends BaseError.extend('UNIMPLEMENTED') {}
11
+ export class InternalError extends BaseError.extend('INTERNAL', 'Internal error') {}
12
12
 
13
- export class ApiError extends BaseError.extend('API_ERROR') {}
13
+ export class TimeoutError extends BaseError.extend('TIMEOUT', 'Timeout') {}
14
14
 
15
- export class SystemError extends BaseError.extend('SYSTEM_ERROR') {}
15
+ export class AbortedError extends BaseError.extend('ABORTED', 'Aborted') {}
16
16
 
17
- export class InternalError extends BaseError.extend('INTERNAL_ERROR') {}
17
+ export class NotImplementedError extends BaseError.extend('NOT_IMPLEMENTED', 'Not implemented') {}