@exodus/errors 1.3.0 → 2.0.0
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/CHANGELOG.md +10 -0
- package/lib/safe-error.d.ts +6 -20
- package/lib/safe-error.js +12 -5
- package/lib/stack.d.ts +1 -0
- package/lib/stack.js +11 -0
- package/lib/utils.d.ts +3 -0
- package/lib/utils.js +1 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.0.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/errors@1.3.0...@exodus/errors@2.0.0) (2025-02-26)
|
|
7
|
+
|
|
8
|
+
### ⚠ BREAKING CHANGES
|
|
9
|
+
|
|
10
|
+
- **errors:** SafeError returns stack trace in the text format (#11581)
|
|
11
|
+
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
- feat(errors)!: SafeError returns stack trace in the text format (#11581)
|
|
15
|
+
|
|
6
16
|
## [1.3.0](https://github.com/ExodusMovement/exodus-hydra/compare/@exodus/errors@1.2.0...@exodus/errors@1.3.0) (2025-02-17)
|
|
7
17
|
|
|
8
18
|
### Features
|
package/lib/safe-error.d.ts
CHANGED
|
@@ -2,16 +2,16 @@ import type { Frame } from './types.js';
|
|
|
2
2
|
type ReadonlySetValues<S> = S extends ReadonlySet<infer T> ? T : never;
|
|
3
3
|
declare const SAFE_NAMES_SET: ReadonlySet<"Error" | "AssertionError" | "TypeError" | "RangeError" | "UnknownError" | "SafeErrorFailedToParse" | "TimeoutError">;
|
|
4
4
|
declare const SAFE_HINTS_SET: ReadonlySet<"broadcastTx" | "otherErr:broadcastTx" | "retry:broadcastTx" | "getNftArguments" | "ethCall" | "ethCall:executionReverted" | "failed to parse error">;
|
|
5
|
-
type SafeName = ReadonlySetValues<typeof SAFE_NAMES_SET>;
|
|
6
|
-
type SafeHint = ReadonlySetValues<typeof SAFE_HINTS_SET>;
|
|
7
|
-
type SafeCode = string & {
|
|
5
|
+
export type SafeName = ReadonlySetValues<typeof SAFE_NAMES_SET>;
|
|
6
|
+
export type SafeHint = ReadonlySetValues<typeof SAFE_HINTS_SET>;
|
|
7
|
+
export type SafeCode = string & {
|
|
8
8
|
__branded_type: 'SafeCodeOutcome';
|
|
9
9
|
};
|
|
10
10
|
type UnknownError = Error & {
|
|
11
11
|
hint?: unknown;
|
|
12
12
|
code?: unknown;
|
|
13
13
|
};
|
|
14
|
-
declare const FACTORY_SYMBOL: unique symbol;
|
|
14
|
+
export declare const FACTORY_SYMBOL: unique symbol;
|
|
15
15
|
export declare class SafeError {
|
|
16
16
|
#private;
|
|
17
17
|
static readonly hints: {
|
|
@@ -47,24 +47,10 @@ export declare class SafeError {
|
|
|
47
47
|
in_app?: boolean | null;
|
|
48
48
|
__proto__: null;
|
|
49
49
|
}[] | undefined;
|
|
50
|
+
get stack(): string | undefined;
|
|
50
51
|
get timestamp(): number;
|
|
51
52
|
toJSON(): {
|
|
52
|
-
|
|
53
|
-
name: "Error" | "AssertionError" | "TypeError" | "RangeError" | "UnknownError" | "SafeErrorFailedToParse" | "TimeoutError";
|
|
54
|
-
code: SafeCode | undefined;
|
|
55
|
-
hint: "broadcastTx" | "otherErr:broadcastTx" | "retry:broadcastTx" | "getNftArguments" | "ethCall" | "ethCall:executionReverted" | "failed to parse error" | undefined;
|
|
56
|
-
stackFrames: {
|
|
57
|
-
function?: string | null;
|
|
58
|
-
method?: string | null;
|
|
59
|
-
file?: string | null;
|
|
60
|
-
line?: number | null;
|
|
61
|
-
column?: number | null;
|
|
62
|
-
async?: boolean | null;
|
|
63
|
-
toplevel?: boolean | null;
|
|
64
|
-
in_app?: boolean | null;
|
|
65
|
-
__proto__: null;
|
|
66
|
-
}[] | undefined;
|
|
67
|
-
timestamp: number;
|
|
53
|
+
[k: string]: any;
|
|
68
54
|
};
|
|
69
55
|
constructor({ name, code, hint, stack, initSymbol, }: {
|
|
70
56
|
name: SafeName;
|
package/lib/safe-error.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import assert from 'minimalistic-assert';
|
|
2
|
-
import parseStackTraceNatively from './stack.js';
|
|
2
|
+
import parseStackTraceNatively, { stackFramesToString } from './stack.js';
|
|
3
|
+
import { omitUndefined } from './utils.js';
|
|
3
4
|
function makeReadonlySet(values) {
|
|
4
5
|
return new Set(values);
|
|
5
6
|
}
|
|
@@ -58,7 +59,7 @@ function isExodusErrorCode(code) {
|
|
|
58
59
|
function isSafeCode(value) {
|
|
59
60
|
return SAFE_CODES_SET.has(value) || isExodusErrorCode(value);
|
|
60
61
|
}
|
|
61
|
-
const FACTORY_SYMBOL = Symbol('SafeError');
|
|
62
|
+
export const FACTORY_SYMBOL = Symbol('SafeError');
|
|
62
63
|
export class SafeError {
|
|
63
64
|
static hints = safeHints;
|
|
64
65
|
static from(err) {
|
|
@@ -113,18 +114,24 @@ export class SafeError {
|
|
|
113
114
|
get stackFrames() {
|
|
114
115
|
return this.#stackFrames?.map((frame) => ({ __proto__: null, ...frame }));
|
|
115
116
|
}
|
|
117
|
+
get stack() {
|
|
118
|
+
const stackTrace = stackFramesToString(this.stackFrames);
|
|
119
|
+
return stackTrace
|
|
120
|
+
? `${this.name}: ${this.code || this.hint || 'unknownHint'}\n${stackTrace}`
|
|
121
|
+
: undefined;
|
|
122
|
+
}
|
|
116
123
|
get timestamp() {
|
|
117
124
|
return this.#timestamp;
|
|
118
125
|
}
|
|
119
126
|
toJSON() {
|
|
120
|
-
return {
|
|
127
|
+
return omitUndefined({
|
|
121
128
|
__proto__: null,
|
|
122
129
|
name: this.name,
|
|
123
130
|
code: this.code,
|
|
124
131
|
hint: this.hint,
|
|
125
|
-
|
|
132
|
+
stack: this.stack,
|
|
126
133
|
timestamp: this.timestamp,
|
|
127
|
-
};
|
|
134
|
+
});
|
|
128
135
|
}
|
|
129
136
|
constructor({ name, code, hint, stack, initSymbol, }) {
|
|
130
137
|
assert(initSymbol === FACTORY_SYMBOL, 'SafeError: use SafeError.from()');
|
package/lib/stack.d.ts
CHANGED
package/lib/stack.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
export function stackFramesToString(frames) {
|
|
2
|
+
if (frames === undefined) {
|
|
3
|
+
return;
|
|
4
|
+
}
|
|
5
|
+
return frames
|
|
6
|
+
.map((frame) => {
|
|
7
|
+
const { function: fn, method, file, line, column } = frame;
|
|
8
|
+
return ` at ${fn || 'unknownFn'}${method ? `.${method}` : ''}${file ? `(${file}${line === null ? '' : `:${line}:${column}`})` : ''}`;
|
|
9
|
+
})
|
|
10
|
+
.join('\n');
|
|
11
|
+
}
|
|
1
12
|
export default function parseStackTraceNatively(err) {
|
|
2
13
|
const { prepareStackTrace } = Error;
|
|
3
14
|
let stack;
|
package/lib/utils.d.ts
ADDED
package/lib/utils.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const omitUndefined = (object) => Object.fromEntries(Object.entries(object).filter(([, value]) => value !== undefined));
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exodus/errors",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.0",
|
|
5
5
|
"description": "Utilities for error handling in client code, such as sanitization",
|
|
6
6
|
"author": "Exodus Movement, Inc.",
|
|
7
7
|
"repository": {
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "b5f5320ef9490bae4794356a815b2f8a376bbf03"
|
|
48
48
|
}
|