@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 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
@@ -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
- __proto__: null;
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
- stackFrames: this.stackFrames,
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
@@ -1,2 +1,3 @@
1
1
  import type { Frame } from './types.js';
2
+ export declare function stackFramesToString(frames?: Frame[]): string | undefined;
2
3
  export default function parseStackTraceNatively(err: Error): Frame[] | undefined;
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
@@ -0,0 +1,3 @@
1
+ export declare const omitUndefined: (object: Record<string, any>) => {
2
+ [k: string]: any;
3
+ };
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": "1.3.0",
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": "114da97a6c05a44949b90563201467852e48f069"
47
+ "gitHead": "b5f5320ef9490bae4794356a815b2f8a376bbf03"
48
48
  }