Skip to content

Commit 40266fd

Browse files
Exposed a static Ono.extend() method that allows Ono to extend Errors that weren't created with Ono
1 parent 1e3e5ed commit 40266fd

File tree

3 files changed

+74
-19
lines changed

3 files changed

+74
-19
lines changed

src/constructor.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
import { extendError } from "./extend-error";
22
import { normalizeArgs, normalizeOptions } from "./normalize";
33
import { toJSON as errorToJSON } from "./to-json";
4-
import { ErrorLike, ErrorLikeConstructor, ErrorLikeConstructorClass, ErrorPOJO, OnoConstructor, OnoError, OnoOptions } from "./types";
4+
import { ErrorLike, ErrorLikeConstructor, ErrorLikeConstructorClass, OnoConstructor, OnoOptions } from "./types";
55

66
const constructor = Ono as OnoConstructor;
77
export { constructor as Ono };
88

9-
/**
10-
* Returns an object containing all properties of the given Error object,
11-
* which can be used with `JSON.stringify()`.
12-
*/
13-
Ono.toJSON = function toJSON<E extends ErrorLike>(error: E) {
14-
return errorToJSON.call(error) as ErrorPOJO & E;
15-
};
16-
179
/**
1810
* Creates an `Ono` instance for a specifc error type.
1911
*/
@@ -25,14 +17,36 @@ function Ono<T extends ErrorLike>(ErrorConstructor: ErrorLikeConstructor<T>, opt
2517
let { originalError, props, message } = normalizeArgs<E, P>(args, options!);
2618

2719
// Create a new error of the specified type
28-
let newError = new (ErrorConstructor as ErrorLikeConstructorClass<T>)(message) as T & E & P & OnoError<T & E & P>;
20+
let newError = new (ErrorConstructor as ErrorLikeConstructorClass<T>)(message);
2921

3022
// Extend the error with the properties of the original error and the `props` object
31-
extendError(newError, originalError, props);
32-
33-
return newError;
23+
return extendError(newError, originalError, props);
3424
}
3525

3626
ono[Symbol.species] = ErrorConstructor;
3727
return ono;
3828
}
29+
30+
/**
31+
* Returns an object containing all properties of the given Error object,
32+
* which can be used with `JSON.stringify()`.
33+
*/
34+
Ono.toJSON = function toJSON(error: ErrorLike) {
35+
return errorToJSON.call(error);
36+
};
37+
38+
/**
39+
* Extends the given Error object with enhanced Ono functionality, such as nested stack traces,
40+
* additional properties, and improved support for `JSON.stringify()`.
41+
*/
42+
Ono.extend = function extend(error: ErrorLike, originalError?: ErrorLike, props?: object) {
43+
if (props || originalError instanceof Error) {
44+
return extendError(error, originalError, props);
45+
}
46+
else if (originalError) {
47+
return extendError(error, undefined, originalError);
48+
}
49+
else {
50+
return extendError(error);
51+
}
52+
};

src/extend-error.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,28 +12,32 @@ const protectedProps: Array<string | symbol> = ["name", "message", "stack"];
1212
* @param originalError - The original error object, if any
1313
* @param props - Additional properties to add, if any
1414
*/
15-
export function extendError<T>(newError: OnoError<T>, originalError?: ErrorPOJO, props?: object) {
16-
extendStack(newError, originalError);
15+
export function extendError<T extends ErrorLike, E extends ErrorLike, P extends object>(error: T, originalError?: E, props?: P) {
16+
let onoError = error as unknown as T & E & P & OnoError<T & E & P>;
17+
18+
extendStack(onoError, originalError);
1719

1820
// Copy properties from the original error
1921
if (originalError && typeof originalError === "object") {
20-
mergeErrors(newError, originalError);
22+
mergeErrors(onoError, originalError);
2123
}
2224

2325
// The default `toJSON` method doesn't output props like `name`, `message`, `stack`, etc.
2426
// So replace it with one that outputs every property of the error.
25-
newError.toJSON = toJSON;
27+
onoError.toJSON = toJSON;
2628

2729
// On Node.js, add support for the `util.inspect()` method
2830
if (addInspectMethod) {
29-
addInspectMethod(newError);
31+
addInspectMethod(onoError);
3032
}
3133

3234
// Finally, copy custom properties that were specified by the user.
3335
// These props OVERWRITE any previous props
3436
if (props && typeof props === "object") {
35-
Object.assign(newError, props);
37+
Object.assign(onoError, props);
3638
}
39+
40+
return onoError;
3741
}
3842

3943
/**

src/types.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,43 @@ export interface OnoConstructor {
2525
* which can be used with `JSON.stringify()`.
2626
*/
2727
toJSON<E extends ErrorLike>(error: E): ErrorPOJO & E;
28+
29+
/**
30+
* Extends the given Error object with enhanced Ono functionality, such as improved support for
31+
* `JSON.stringify()`.
32+
*
33+
* @param error - The error object to extend. This object instance will be modified and returned.
34+
*/
35+
extend<T extends ErrorLike>(error: T): T & OnoError<T>;
36+
37+
/**
38+
* Extends the given Error object with enhanced Ono functionality, such as additional properties
39+
* and improved support for `JSON.stringify()`.
40+
*
41+
* @param error - The error object to extend. This object instance will be modified and returned.
42+
* @param props - An object whose properties will be added to the error
43+
*/
44+
extend<T extends ErrorLike, P extends object>(error: T, props?: P): T & P & OnoError<T & P>;
45+
46+
/**
47+
* Extends the given Error object with enhanced Ono functionality, such as nested stack traces
48+
* and improved support for `JSON.stringify()`.
49+
*
50+
* @param error - The error object to extend. This object instance will be modified and returned.
51+
* @param originalError - The original error. This error's stack trace will be added to the error's stack trace.
52+
*/
53+
extend<T extends ErrorLike, E extends ErrorLike>(error: T, originalError?: E): T & E & OnoError<T & E>;
54+
55+
/**
56+
* Extends the given Error object with enhanced Ono functionality, such as nested stack traces,
57+
* additional properties, and improved support for `JSON.stringify()`.
58+
*
59+
* @param error - The error object to extend. This object instance will be modified and returned.
60+
* @param originalError - The original error. This error's stack trace will be added to the error's stack trace.
61+
* @param props - An object whose properties will be added to the error
62+
*/
63+
extend<T extends ErrorLike, E extends ErrorLike, P extends object>(error: T, originalError?: E, props?: P)
64+
: T & E & P & OnoError<T & E & P>;
2865
}
2966

3067
/**

0 commit comments

Comments
 (0)