@layerzerolabs/common-error-utils 0.2.68 → 0.2.69

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": "@layerzerolabs/common-error-utils",
3
- "version": "0.2.68",
3
+ "version": "0.2.69",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,6 +13,9 @@
13
13
  "main": "./dist/index.cjs",
14
14
  "module": "./dist/index.js",
15
15
  "types": "./dist/index.d.ts",
16
+ "files": [
17
+ "dist/**/*"
18
+ ],
16
19
  "dependencies": {
17
20
  "exponential-backoff": "^3.1.1",
18
21
  "ms": "^2.1.3"
@@ -21,8 +24,8 @@
21
24
  "@types/ms": "^2.1.0",
22
25
  "tsup": "^8.4.0",
23
26
  "vitest": "^3.2.3",
24
- "@layerzerolabs/tsup-configuration": "0.2.68",
25
- "@layerzerolabs/typescript-configuration": "0.2.68"
27
+ "@layerzerolabs/tsup-configuration": "0.2.69",
28
+ "@layerzerolabs/typescript-configuration": "0.2.69"
26
29
  },
27
30
  "publishConfig": {
28
31
  "access": "public",
@@ -30,7 +33,8 @@
30
33
  },
31
34
  "externalRepoConfig": {
32
35
  "targets": [
33
- "audit-external"
36
+ "audit-external",
37
+ "onesig-client"
34
38
  ]
35
39
  },
36
40
  "scripts": {
@@ -1,39 +0,0 @@
1
-  WARN  Issue while reading "/home/runner/work/monorepo-internal/monorepo-internal/.npmrc". Failed to replace env in config: ${NPM_TOKEN}
2
-
3
- > @layerzerolabs/common-error-utils@0.0.0 build /home/runner/work/monorepo-internal/monorepo-internal/packages/common/common-error-utils
4
- > tsup
5
-
6
- CLI Building entry: src/errors.ts, src/index.ts, src/retry.ts
7
- CLI Using tsconfig: tsconfig.json
8
- CLI tsup v8.5.1
9
- CLI Using tsup config: /home/runner/work/monorepo-internal/monorepo-internal/packages/common/common-error-utils/tsup.config.ts
10
- CLI Target: ES2023
11
- CLI Cleaning output folder
12
- CJS Build start
13
- ESM Build start
14
- CJS dist/index.cjs 1.81 KB
15
- CJS dist/YJF4D23A.cjs 245.00 B
16
- CJS dist/errors.cjs 1.63 KB
17
- CJS dist/MXJDS64O.cjs 5.06 KB
18
- CJS dist/CSP5OI2I.cjs 1.55 KB
19
- CJS dist/retry.cjs 302.00 B
20
- CJS dist/index.cjs.map 70.00 B
21
- CJS dist/YJF4D23A.cjs.map 73.00 B
22
- CJS dist/errors.cjs.map 71.00 B
23
- CJS dist/MXJDS64O.cjs.map 10.18 KB
24
- CJS dist/CSP5OI2I.cjs.map 5.03 KB
25
- CJS dist/retry.cjs.map 70.00 B
26
- CJS ⚡️ Build success in 215ms
27
- ESM dist/errors.js 315.00 B
28
- ESM dist/retry.js 143.00 B
29
- ESM dist/VUOMXK5T.js 222.00 B
30
- ESM dist/HSJL4TXR.js 4.62 KB
31
- ESM dist/WUDCWRMR.js 1.27 KB
32
- ESM dist/index.js 365.00 B
33
- ESM dist/errors.js.map 70.00 B
34
- ESM dist/retry.js.map 69.00 B
35
- ESM dist/VUOMXK5T.js.map 72.00 B
36
- ESM dist/HSJL4TXR.js.map 10.17 KB
37
- ESM dist/WUDCWRMR.js.map 5.01 KB
38
- ESM dist/index.js.map 69.00 B
39
- ESM ⚡️ Build success in 216ms
@@ -1,8 +0,0 @@
1
-
2
- > @layerzerolabs/common-error-utils@0.0.0 lint /home/runner/work/monorepo-internal/monorepo-internal/packages/common/common-error-utils
3
- > eslint . --max-warnings 0 || (eslint . --fix --max-warnings 0 && false)
4
-
5
- (node:65553) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///home/runner/work/monorepo-internal/monorepo-internal/eslint.config.js?mtime=1775694520701 is not specified and it doesn't parse as CommonJS.
6
- Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
7
- To eliminate this warning, add "type": "module" to /home/runner/work/monorepo-internal/monorepo-internal/package.json.
8
- (Use `node --trace-warnings ...` to show where the warning was created)
@@ -1,33 +0,0 @@
1
-
2
- > @layerzerolabs/common-error-utils@0.0.0 test /home/runner/work/monorepo-internal/monorepo-internal/packages/common/common-error-utils
3
- > vitest --run --pass-with-no-tests --typecheck
4
-
5
- Testing types with tsc and vue-tsc is an experimental feature.
6
- Breaking changes might not follow SemVer, please pin Vitest's version when using it.
7
-
8
-  RUN  v3.2.4 /home/runner/work/monorepo-internal/monorepo-internal/packages/common/common-error-utils
9
-
10
- stdout | tests/error.test.ts > SerializableError > wraps simple error
11
- SomeError constructor called {
12
- cause: Error: Some error 2
13
- at /home/runner/work/monorepo-internal/monorepo-internal/packages/common/common-error-utils/tests/error.test.ts:33:21
14
- at file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:155:11
15
- at file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:752:26
16
- at file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:1897:20
17
- at new Promise (<anonymous>)
18
- at runWithTimeout (file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:1863:10)
19
- at runTest (file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:1574:12)
20
-  at processTicksAndRejections (node:internal/process/task_queues:105:5)
21
- at runSuite (file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:1729:8)
22
- at runSuite (file:///home/runner/work/monorepo-internal/monorepo-internal/node_modules/.pnpm/@vitest+runner@3.2.4/node_modules/@vitest/runner/dist/chunk-hooks.js:1729:8)
23
- }
24
-
25
- ✓ tests/error.test.ts (3 tests) 12ms
26
- ✓ tests/retry.test.ts (6 tests) 71ms
27
-
28
-  Test Files  2 passed (2)
29
-  Tests  9 passed (9)
30
- Type Errors  no errors
31
-  Start at  00:31:09
32
-  Duration  805ms (transform 144ms, setup 0ms, collect 200ms, tests 83ms, environment 0ms, prepare 250ms)
33
-
package/src/errors.ts DELETED
@@ -1,153 +0,0 @@
1
- const extractMessageFromJsonRpcError = (err: any): string => {
2
- try {
3
- if (typeof err.body === 'object' && err.body.message) {
4
- return err.body.message;
5
- }
6
- const parsedBody = JSON.parse(err.body);
7
- return parsedBody?.error?.message;
8
- } catch {
9
- return 'unknown';
10
- }
11
- };
12
-
13
- export function convertErrorToObject(err: any): any {
14
- return JSON.parse(JSON.stringify(err, Object.getOwnPropertyNames(err)));
15
- }
16
-
17
- export function normalizeError(err: any) {
18
- const error = convertErrorToObject(err);
19
- return {
20
- // Normal Error properties
21
- ...(error.name ? { name: error.name } : {}),
22
- ...(error.message ? { message: error.message } : {}),
23
- ...(error.stack ? { stack: error.stack } : {}),
24
- // Rpc properties
25
- ...(error.reason ? { reason: error.reason } : {}),
26
- ...(error.code ? { code: error.code } : {}),
27
- ...(error.event ? { event: error.event } : {}),
28
- ...(error.body ? { body: extractMessageFromJsonRpcError(error) } : {}),
29
- };
30
- }
31
-
32
- // Removes the last argument if it is an ErrorOptions
33
- type RemoveErrorOptions<T extends any[]> = T extends [...infer U, ErrorOptions?] ? U : never;
34
-
35
- /**
36
- * Base class for all serializable errors.
37
- * This class is designed to be extended by other error classes.
38
- * It provides a way to wrap errors and a way to check if an error is in the stack of a specific error class.
39
- * All errors that extend this class *must* have error options as the last argument in their constructor.
40
- */
41
- export abstract class SerializableError extends Error {
42
- details: string[];
43
- /*
44
- * The instance of the error that was wrapped, if any.
45
- * Creates a linked list of error objects.
46
- * Only exists if the error hasn't been serialized and deserialized.
47
- */
48
- cause: unknown;
49
- constructor(message: string, options?: ErrorOptions) {
50
- super(message, options);
51
- // for some reason, we need to set the cause directly on the instance, even after calling super
52
- this.cause = options?.cause;
53
- this.name = this.constructor.name;
54
- this.details = [this.constructor.name, 'SerializableError'];
55
- }
56
-
57
- /*
58
- * Checks if the error is an instance of the current class or a subclass. Returns the error if it is.
59
- * We can't type the error as more than SerializableError because it could have been serialized and deserialized,
60
- * which could make it lose extra fields.
61
- */
62
- static inStackOf<T extends abstract new (...args: any) => any>(
63
- this: T,
64
- error: any,
65
- ): SerializableError | undefined {
66
- if (error?.details?.includes(this.name)) {
67
- return error as SerializableError;
68
- } else if (error?.cause?.details?.includes(this.name)) {
69
- return error.cause as SerializableError;
70
- }
71
- return undefined;
72
- }
73
-
74
- // We could limit this to only wrap serializable errors, but that could limit the flexibility of the error system.
75
- static wrap<T extends new (...args: any) => SerializableError>(
76
- this: T,
77
- error: any,
78
- // Remove the optional error arguments
79
- ...args: RemoveErrorOptions<ConstructorParameters<T>>
80
- ): InstanceType<T> {
81
- const wrappedError = new this(...args, { cause: error });
82
-
83
- wrappedError.details = error?.details
84
- ? [wrappedError.name, ...error.details]
85
- : [wrappedError.name, 'SerializableError', error?.name ?? 'UnknownError'];
86
-
87
- wrappedError.message = `${wrappedError.message} > ${error?.message ?? String(error)}`;
88
-
89
- return wrappedError as InstanceType<T>;
90
- }
91
- }
92
-
93
- export class NonRetryableError extends SerializableError {
94
- constructor(message: string, options?: ErrorOptions) {
95
- super(message, options);
96
- }
97
- }
98
-
99
- export class NotFoundError extends SerializableError {
100
- constructor(message?: string, options?: ErrorOptions) {
101
- super(message ? `Not found: ${message}` : 'Not found', options);
102
- }
103
- }
104
-
105
- // TODO: extend this for chain specific providers
106
- export class ProviderError extends SerializableError {
107
- constructor(providerUri: string, options?: ErrorOptions) {
108
- super(`Provider error at host '${ProviderError.parseHost(providerUri)}'`, options);
109
- }
110
-
111
- private static parseHost(providerUri: string): string {
112
- try {
113
- const url = new URL(providerUri);
114
- return url.host;
115
- } catch {
116
- return 'UNKNOWN_HOST';
117
- }
118
- }
119
- }
120
-
121
- export class NonEmittableError extends SerializableError {
122
- constructor(message: string, options?: ErrorOptions) {
123
- super(message, options);
124
- this.name = 'NonEmittableError';
125
- }
126
- }
127
-
128
- export class QuorumNotAchievedYet extends SerializableError {
129
- constructor(options?: ErrorOptions) {
130
- super('The quorum was not achieved yet', options);
131
- }
132
- }
133
-
134
- export class MultiError extends Error {
135
- constructor(public readonly errs: any[]) {
136
- super(errs.map((err) => err.message).join(', '));
137
- }
138
- }
139
-
140
- export const throwError = <Err extends Error>(
141
- message: string,
142
- error?: (message: string) => Err,
143
- ): never => {
144
- throw error?.(message) ?? new Error(message);
145
- };
146
-
147
- /**
148
- * Assert that a value is never.
149
- * Most useful for enforcing exhaustive switch statements.
150
- */
151
- export const assertUnreachable = (value: never): never => {
152
- throw new NonRetryableError(`Unreachable value: ${value}`);
153
- };
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export * from './errors';
2
- export * from './retry';
package/src/retry.ts DELETED
@@ -1,97 +0,0 @@
1
- import { backOff } from 'exponential-backoff';
2
- import type { StringValue } from 'ms';
3
- import ms from 'ms';
4
-
5
- export interface RetryPolicy {
6
- /**
7
- * Maximum time of a single execution attempt.
8
- * This timeout should be as short as the longest possible execution of the Activity body.
9
- *
10
- * @default 10 minutes
11
- * @format {@link https://www.npmjs.com/package/ms | ms-formatted string}
12
- */
13
- startToCloseTimeout?: StringValue;
14
-
15
- /**
16
- * Coefficient used to calculate the next retry interval.
17
- * The next retry interval is previous interval multiplied by this coefficient.
18
- * @minimum 1
19
- * @default 2
20
- */
21
- backoffCoefficient?: number;
22
-
23
- /**
24
- * Interval of the first retry.
25
- * If coefficient is 1 then it is used for all retries
26
- * @format {@link https://www.npmjs.com/package/ms | ms-formatted string}
27
- * @default 1 second
28
- */
29
- initialInterval?: StringValue;
30
-
31
- /**
32
- * Maximum number of attempts. When exceeded, retries stop.
33
- *
34
- * @default Infinity
35
- */
36
- maximumAttempts?: number;
37
-
38
- /**
39
- * Maximum interval between retries.
40
- * Exponential backoff leads to interval increase.
41
- * This value is the cap of the increase.
42
- *
43
- * @default 100x of {@link initialInterval}
44
- * @format {@link https://www.npmjs.com/package/ms | ms-formatted string}
45
- */
46
- maximumInterval?: StringValue;
47
-
48
- /**
49
- * List of application failures types to not retry.
50
- */
51
- nonRetryableErrorTypes?: string[];
52
- }
53
-
54
- /**
55
- * Executes a function with a retry policy.
56
- * @param fn - The function to execute.
57
- * @param policy - The retry policy to apply.
58
- * @param shouldRetry - A callback that determines if the error is retryable besides the nonRetryableErrorTypes.
59
- * @return A promise that resolves to the result of the function or rejects with an error.
60
- * @throws Error if the function fails after all retries.
61
- */
62
- export const runWithRetryPolicy = <T = unknown>(
63
- fn: () => Promise<T>,
64
- policy?: RetryPolicy,
65
- shouldRetry?: (err: any) => boolean,
66
- ): Promise<T> => {
67
- const perTryTimeout = ms(policy?.startToCloseTimeout ?? '10 minutes');
68
- const numOfAttempts = policy?.maximumAttempts ?? Infinity;
69
- const startingDelay = ms(policy?.initialInterval ?? '1s');
70
- const maxDelay = policy?.maximumInterval ? ms(policy.maximumInterval) : startingDelay * 100;
71
- const timeMultiple = Math.max(policy?.backoffCoefficient ?? 2, 1);
72
- const nonRetryableErrorTypes = policy?.nonRetryableErrorTypes ?? [];
73
-
74
- return backOff(
75
- () =>
76
- new Promise((resolve, reject) => {
77
- fn().then(resolve).catch(reject);
78
- setTimeout(() => {
79
- reject(new Error(`Execution timed out after ${perTryTimeout}ms`));
80
- }, perTryTimeout);
81
- }),
82
- {
83
- maxDelay,
84
- startingDelay,
85
- jitter: 'full',
86
- timeMultiple,
87
- numOfAttempts,
88
- retry: async (error: any) => {
89
- const errorType = error?.constructor?.name ?? error?.name;
90
- return (
91
- !nonRetryableErrorTypes.includes(errorType) &&
92
- (shouldRetry ? shouldRetry(error) : true)
93
- );
94
- },
95
- },
96
- );
97
- };
@@ -1,40 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import { NotFoundError, SerializableError } from './../src/';
4
-
5
- describe('SerializableError', () => {
6
- it('should check if error is in stack', () => {
7
- const err = new NotFoundError('User');
8
- expect(err.name).toBe('NotFoundError');
9
- expect(err.message).toBe('Not found: User');
10
- expect(err.cause).toBeUndefined();
11
- expect(err.details).toEqual(['NotFoundError', 'SerializableError']);
12
- expect(NotFoundError.inStackOf(err)).toBe(err);
13
- });
14
-
15
- it('should wrap an error', () => {
16
- const originalError = new Error('No rows returned');
17
- const wrappedError = NotFoundError.wrap(originalError, 'User');
18
-
19
- expect(wrappedError.name).toBe('NotFoundError');
20
- expect(wrappedError.message).toBe('Not found: User > No rows returned');
21
- expect(wrappedError.cause).toBe(originalError);
22
- expect(wrappedError.details).toEqual(['NotFoundError', 'SerializableError', 'Error']);
23
- });
24
-
25
- it('wraps simple error', () => {
26
- class SomeError extends SerializableError {
27
- constructor(opts: ErrorOptions) {
28
- console.log('SomeError constructor called', opts);
29
- super('Some error', opts);
30
- }
31
- }
32
-
33
- const err = new Error('Some error 2');
34
- const wrapped = SomeError.wrap(err);
35
- expect(wrapped.name).toBe('SomeError');
36
- expect(wrapped.message).toBe('Some error > Some error 2');
37
- expect(wrapped.cause).toBe(err);
38
- expect(wrapped.details).toEqual(['SomeError', 'SerializableError', 'Error']);
39
- });
40
- });
@@ -1,110 +0,0 @@
1
- import { backOff } from 'exponential-backoff';
2
- import { afterEach, describe, expect, test, vi } from 'vitest';
3
-
4
- import { runWithRetryPolicy } from '../src/retry';
5
-
6
- vi.mock('exponential-backoff', async (importOriginal) => {
7
- const originalModule = await importOriginal<typeof import('exponential-backoff')>();
8
- return {
9
- ...originalModule,
10
- backOff: vi.fn(originalModule.backOff),
11
- };
12
- });
13
-
14
- const mockedBackOff = vi.mocked(backOff);
15
-
16
- describe('runWithRetryPolicy', () => {
17
- afterEach(() => {
18
- vi.clearAllMocks();
19
- });
20
-
21
- test('startToCloseTimeout', async () => {
22
- const longRunningFn = () => new Promise(() => {}); // Never resolves
23
-
24
- await expect(
25
- runWithRetryPolicy(longRunningFn, {
26
- startToCloseTimeout: '50ms',
27
- maximumAttempts: 1,
28
- }),
29
- ).rejects.toThrow('Execution timed out after 50ms');
30
- });
31
-
32
- test('maximumAttempts', async () => {
33
- const failingFn = vi.fn().mockRejectedValue(new Error('simulated failure'));
34
-
35
- await expect(
36
- runWithRetryPolicy(failingFn, {
37
- maximumAttempts: 3,
38
- initialInterval: '1ms',
39
- }),
40
- ).rejects.toThrow('simulated failure');
41
-
42
- expect(mockedBackOff).toHaveBeenCalledWith(
43
- expect.any(Function),
44
- expect.objectContaining({ numOfAttempts: 3 }),
45
- );
46
- expect(failingFn).toHaveBeenCalledTimes(3);
47
- });
48
-
49
- test('initialInterval', async () => {
50
- const fn = async () => {};
51
-
52
- await runWithRetryPolicy(fn, {
53
- initialInterval: '5s',
54
- });
55
-
56
- expect(mockedBackOff).toHaveBeenCalledWith(
57
- expect.any(Function),
58
- expect.objectContaining({ startingDelay: 5000 }),
59
- );
60
- });
61
-
62
- test('maximumInterval', async () => {
63
- const fn = async () => {};
64
- await runWithRetryPolicy(fn, {
65
- maximumInterval: '10s',
66
- });
67
- expect(mockedBackOff).toHaveBeenCalledWith(
68
- expect.any(Function),
69
- expect.objectContaining({ maxDelay: 10000 }),
70
- );
71
- });
72
-
73
- test('backoffCoefficient', async () => {
74
- const fn = async () => {};
75
- await runWithRetryPolicy(fn, {
76
- backoffCoefficient: 3,
77
- });
78
- expect(mockedBackOff).toHaveBeenCalledWith(
79
- expect.any(Function),
80
- expect.objectContaining({ timeMultiple: 3 }),
81
- );
82
- });
83
-
84
- test('nonRetryableErrorTypes', async () => {
85
- class CustomError extends Error {
86
- constructor(message: string) {
87
- super(message);
88
- this.name = 'CustomError';
89
- }
90
- }
91
-
92
- const retryableError = new Error('A retryable error');
93
- const nonRetryableError = new CustomError('A non-retryable error');
94
-
95
- const failingFn = vi
96
- .fn()
97
- .mockRejectedValueOnce(retryableError)
98
- .mockRejectedValueOnce(nonRetryableError);
99
-
100
- await expect(
101
- runWithRetryPolicy(failingFn, {
102
- maximumAttempts: 5,
103
- initialInterval: '1ms',
104
- nonRetryableErrorTypes: ['CustomError'],
105
- }),
106
- ).rejects.toThrow(nonRetryableError);
107
-
108
- expect(failingFn).toHaveBeenCalledTimes(2);
109
- });
110
- });
package/tsconfig.json DELETED
@@ -1,20 +0,0 @@
1
- {
2
- "extends": "@layerzerolabs/typescript-configuration/tsconfig.base.json",
3
- "compilerOptions": {
4
- "rootDir": "./src",
5
- "outDir": "./dist",
6
- "strictPropertyInitialization": false,
7
- "noUnusedLocals": false,
8
- "noUnusedParameters": false,
9
- "jsx": "react-jsx"
10
- },
11
- "exclude": [
12
- "node_modules",
13
- "**/__mocks__/*",
14
- "**/__tests__/*",
15
- "**/*.spec.ts",
16
- "**/*.test.ts",
17
- "dist"
18
- ],
19
- "include": ["src/**/*"]
20
- }
package/tsup.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { defineConfig } from 'tsup';
2
-
3
- import { createPackageTsupConfig } from '@layerzerolabs/tsup-configuration';
4
-
5
- export default defineConfig(({ watch }) => ({
6
- ...createPackageTsupConfig(),
7
- clean: !watch,
8
- }));