@eleva-io/erp-sdk 0.1.147 → 0.1.149
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/dist/cjs/errors/catalog.d.ts +28 -3
- package/dist/cjs/errors/catalog.d.ts.map +1 -1
- package/dist/cjs/errors/catalog.js +2 -0
- package/dist/cjs/errors/catalog.js.map +1 -1
- package/dist/cjs/errors/catalog_api.d.ts +15 -2
- package/dist/cjs/errors/catalog_api.d.ts.map +1 -1
- package/dist/cjs/errors/catalog_api.js +10 -1
- package/dist/cjs/errors/catalog_api.js.map +1 -1
- package/dist/cjs/errors/catalog_base.d.ts +42 -2
- package/dist/cjs/errors/catalog_base.d.ts.map +1 -1
- package/dist/cjs/errors/catalog_base.js +37 -0
- package/dist/cjs/errors/catalog_base.js.map +1 -1
- package/dist/cjs/errors/catalog_types.d.ts +24 -0
- package/dist/cjs/errors/catalog_types.d.ts.map +1 -1
- package/dist/cjs/errors/catalog_types.js +6 -0
- package/dist/cjs/errors/catalog_types.js.map +1 -1
- package/dist/cjs/errors/errors.d.ts +140 -34
- package/dist/cjs/errors/errors.d.ts.map +1 -1
- package/dist/cjs/errors/errors.js +121 -74
- package/dist/cjs/errors/errors.js.map +1 -1
- package/dist/cjs/errors/errors.spec.js +12 -0
- package/dist/cjs/errors/errors.spec.js.map +1 -1
- package/dist/cjs/errors/errors_remote.d.ts +58 -20
- package/dist/cjs/errors/errors_remote.d.ts.map +1 -1
- package/dist/cjs/errors/errors_remote.js +22 -0
- package/dist/cjs/errors/errors_remote.js.map +1 -1
- package/dist/cjs/errors/errors_remote.spec.js +57 -9
- package/dist/cjs/errors/errors_remote.spec.js.map +1 -1
- package/dist/cjs/errors/index.d.ts +19 -0
- package/dist/cjs/errors/index.d.ts.map +1 -1
- package/dist/cjs/errors/index.js +19 -0
- package/dist/cjs/errors/index.js.map +1 -1
- package/dist/cjs/utils/errors.d.ts.map +1 -1
- package/dist/cjs/utils/errors.js +3 -1
- package/dist/cjs/utils/errors.js.map +1 -1
- package/dist/cjs/utils/http.js +10 -10
- package/dist/cjs/utils/http.js.map +1 -1
- package/dist/esm/errors/catalog.d.ts +28 -3
- package/dist/esm/errors/catalog.d.ts.map +1 -1
- package/dist/esm/errors/catalog.js +2 -0
- package/dist/esm/errors/catalog.js.map +1 -1
- package/dist/esm/errors/catalog_api.d.ts +15 -2
- package/dist/esm/errors/catalog_api.d.ts.map +1 -1
- package/dist/esm/errors/catalog_api.js +10 -1
- package/dist/esm/errors/catalog_api.js.map +1 -1
- package/dist/esm/errors/catalog_base.d.ts +42 -2
- package/dist/esm/errors/catalog_base.d.ts.map +1 -1
- package/dist/esm/errors/catalog_base.js +37 -0
- package/dist/esm/errors/catalog_base.js.map +1 -1
- package/dist/esm/errors/catalog_types.d.ts +24 -0
- package/dist/esm/errors/catalog_types.d.ts.map +1 -1
- package/dist/esm/errors/catalog_types.js +6 -0
- package/dist/esm/errors/catalog_types.js.map +1 -1
- package/dist/esm/errors/errors.d.ts +140 -34
- package/dist/esm/errors/errors.d.ts.map +1 -1
- package/dist/esm/errors/errors.js +121 -74
- package/dist/esm/errors/errors.js.map +1 -1
- package/dist/esm/errors/errors.spec.js +12 -0
- package/dist/esm/errors/errors.spec.js.map +1 -1
- package/dist/esm/errors/errors_remote.d.ts +58 -20
- package/dist/esm/errors/errors_remote.d.ts.map +1 -1
- package/dist/esm/errors/errors_remote.js +22 -0
- package/dist/esm/errors/errors_remote.js.map +1 -1
- package/dist/esm/errors/errors_remote.spec.js +57 -9
- package/dist/esm/errors/errors_remote.spec.js.map +1 -1
- package/dist/esm/errors/index.d.ts +19 -0
- package/dist/esm/errors/index.d.ts.map +1 -1
- package/dist/esm/errors/index.js +19 -0
- package/dist/esm/errors/index.js.map +1 -1
- package/dist/esm/utils/errors.d.ts.map +1 -1
- package/dist/esm/utils/errors.js +3 -1
- package/dist/esm/utils/errors.js.map +1 -1
- package/dist/esm/utils/http.js +10 -10
- package/dist/esm/utils/http.js.map +1 -1
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { ErrorCode, type ErrorDetails } from './catalog';
|
|
|
3
3
|
import { ErrorKind } from './catalog_types';
|
|
4
4
|
import { BASE_ERROR_CODES } from './catalog_base';
|
|
5
5
|
import { API_ERROR_CODES } from './catalog_api';
|
|
6
|
+
/** Plain-object representation of an `ElevaError`, suitable for serialisation. */
|
|
6
7
|
export interface ElevaErrorJSON<C extends ErrorCode = ErrorCode> {
|
|
7
8
|
code: C | string;
|
|
8
9
|
kind: ErrorKind;
|
|
@@ -10,83 +11,188 @@ export interface ElevaErrorJSON<C extends ErrorCode = ErrorCode> {
|
|
|
10
11
|
message: string;
|
|
11
12
|
details: ErrorDetails<C>;
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Slim response payload for API consumers.
|
|
16
|
+
* `SYSTEM` errors omit `details`; `DOMAIN` errors include it.
|
|
17
|
+
*/
|
|
13
18
|
export interface ElevaErrorResponse<C extends ErrorCode = ErrorCode> {
|
|
14
19
|
code: ElevaErrorJSON<C>['code'];
|
|
15
20
|
message: ElevaErrorJSON<C>['message'];
|
|
16
21
|
details?: ElevaErrorJSON<C>['details'];
|
|
17
22
|
}
|
|
23
|
+
/** Constructor arguments for `ElevaError`. Adds optional `cause` for error chaining. */
|
|
18
24
|
export type ElevaErrorArgs<C extends ErrorCode> = ElevaErrorJSON<C> & {
|
|
25
|
+
/** The original error forwarded to `Error.cause`. */
|
|
19
26
|
cause?: unknown;
|
|
20
27
|
};
|
|
28
|
+
/**
|
|
29
|
+
* Central error class for the Eleva ERP SDK.
|
|
30
|
+
*
|
|
31
|
+
* Extends `Error` with structured metadata: `code`, `kind`, `status`, and typed `details`.
|
|
32
|
+
*
|
|
33
|
+
* ```ts
|
|
34
|
+
* // Create
|
|
35
|
+
* throw ElevaError.notFound({ entity: 'Invoice' })
|
|
36
|
+
* throw ElevaError.conflict({ details: [{ key: 'email', value: 'a@b.com', cause: 'duplicate' }] })
|
|
37
|
+
*
|
|
38
|
+
* // Narrow
|
|
39
|
+
* if (err instanceof ElevaError && err.is(ERROR_CODES.NOT_FOUND)) {
|
|
40
|
+
* console.log(err.details.entity) // string
|
|
41
|
+
* }
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* Serialisation: `toJSON()` for logging, `toResponse()` for sanitised API output.
|
|
45
|
+
*/
|
|
21
46
|
export declare class ElevaError<C extends ErrorCode = ErrorCode> extends Error {
|
|
47
|
+
/** Error code constant identifying the failure condition. */
|
|
22
48
|
readonly code: C | string;
|
|
49
|
+
/** `DOMAIN` (safe to expose) or `SYSTEM` (sanitised before sending to clients). */
|
|
23
50
|
readonly kind: ErrorKind;
|
|
51
|
+
/** HTTP status code for this error. */
|
|
24
52
|
readonly status: number;
|
|
53
|
+
/** Structured, code-specific failure context. */
|
|
25
54
|
readonly details: ErrorDetails<C>;
|
|
26
55
|
constructor(args: ElevaErrorArgs<C>);
|
|
27
|
-
|
|
56
|
+
/**
|
|
57
|
+
* Type-guard: narrows to `ElevaError<K>` when `this.code === code`.
|
|
58
|
+
* After a positive check `this.details` is fully typed for `K`.
|
|
59
|
+
* @example
|
|
60
|
+
* if (err.is(ERROR_CODES.NOT_FOUND)) console.log(err.details.entity)
|
|
61
|
+
*/
|
|
62
|
+
is<K extends ErrorCode>(code: K | string): this is ElevaError<K>;
|
|
63
|
+
/** Full serialised representation for logging / diagnostics. */
|
|
28
64
|
toJSON(): ElevaErrorJSON<C>;
|
|
29
65
|
toString(): string;
|
|
66
|
+
/**
|
|
67
|
+
* Sanitised payload safe for API responses.
|
|
68
|
+
* `SYSTEM` errors replace the message with a generic string; `DOMAIN` errors include `details`.
|
|
69
|
+
*/
|
|
30
70
|
toResponse(): ElevaErrorResponse<C>;
|
|
71
|
+
/**
|
|
72
|
+
* Parses an unknown value into `ElevaErrorArgs`. Shared by `parse()` and `RemoteElevaError.from()`.
|
|
73
|
+
*
|
|
74
|
+
* Strategy: validate against `errorSchema` → look up known codes in the catalog →
|
|
75
|
+
* fall back to `INTERNAL_SERVER_ERROR` for unrecognised codes or malformed payloads →
|
|
76
|
+
* accept legacy `errors` field as a fallback for `details`.
|
|
77
|
+
*/
|
|
31
78
|
protected static _parsePayload(value: unknown): ElevaErrorArgs<ErrorCode>;
|
|
79
|
+
/** Deserialises an unknown value into an `ElevaError`. Unrecognised payloads become `INTERNAL_SERVER_ERROR`. */
|
|
32
80
|
static parse(value: unknown): ElevaError<ErrorCode>;
|
|
81
|
+
/** Converts a `ZodError` into a `VALIDATION` error, preserving field paths and rule codes. */
|
|
33
82
|
static fromZodError<T>(error: z.ZodError<T>): ElevaError<BASE_ERROR_CODES.VALIDATION>;
|
|
83
|
+
/** Creates a `VALIDATION` error from a pre-built array of issue descriptors. */
|
|
34
84
|
static validation(args: {
|
|
35
85
|
errors: ErrorDetails<BASE_ERROR_CODES.VALIDATION>['errors'];
|
|
36
86
|
message?: string;
|
|
37
87
|
}): ElevaError<BASE_ERROR_CODES.VALIDATION>;
|
|
88
|
+
/** Creates a `VALIDATION` error for a single invalid field. Convenience wrapper around `validation()`. */
|
|
38
89
|
static invalidField(args: {
|
|
39
90
|
error: ErrorDetails<BASE_ERROR_CODES.VALIDATION>['errors'][number];
|
|
40
91
|
message?: string;
|
|
41
92
|
}): ElevaError<BASE_ERROR_CODES.VALIDATION>;
|
|
42
|
-
|
|
93
|
+
/** HTTP 400 — request is malformed or has invalid parameters outside of validation. */
|
|
94
|
+
static readonly badRequest: (args?: {
|
|
43
95
|
message?: string;
|
|
44
|
-
details?:
|
|
45
|
-
|
|
46
|
-
|
|
96
|
+
details?: {
|
|
97
|
+
field?: string | undefined;
|
|
98
|
+
reason?: string | undefined;
|
|
99
|
+
} | undefined;
|
|
100
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.BAD_REQUEST>;
|
|
101
|
+
/** HTTP 401 — credentials are missing, expired, or invalid. Caller must re-authenticate. */
|
|
102
|
+
static readonly authentication: (args?: {
|
|
47
103
|
message?: string;
|
|
48
|
-
details?:
|
|
49
|
-
|
|
50
|
-
|
|
104
|
+
details?: {
|
|
105
|
+
reason?: string | undefined;
|
|
106
|
+
} | undefined;
|
|
107
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.AUTHENTICATION>;
|
|
108
|
+
/** HTTP 403 — authenticated but lacks the required scope or permission. */
|
|
109
|
+
static readonly unauthorized: (args?: {
|
|
51
110
|
message?: string;
|
|
52
|
-
details?:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
111
|
+
details?: {
|
|
112
|
+
requiredScope?: string | undefined;
|
|
113
|
+
resource?: string | undefined;
|
|
114
|
+
} | undefined;
|
|
115
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.UNAUTHORIZED>;
|
|
116
|
+
/**
|
|
117
|
+
* HTTP 404 — no resource found for the given identifier.
|
|
118
|
+
* @param args.entity - Entity type that was not found (e.g. `"Invoice"`).
|
|
119
|
+
*/
|
|
120
|
+
static readonly notFound: (args: Record<"entity", string> & {
|
|
56
121
|
message?: string;
|
|
57
|
-
})
|
|
58
|
-
|
|
122
|
+
}) => ElevaError<BASE_ERROR_CODES.NOT_FOUND>;
|
|
123
|
+
/** HTTP 406 — server cannot produce a response matching the `Accept` header. */
|
|
124
|
+
static readonly notAcceptable: (args?: {
|
|
59
125
|
message?: string;
|
|
60
|
-
details?:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
126
|
+
details?: {
|
|
127
|
+
acceptedTypes?: string[] | undefined;
|
|
128
|
+
} | undefined;
|
|
129
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.NOT_ACCEPTABLE>;
|
|
130
|
+
/** HTTP 409 — operation violates a uniqueness or integrity constraint. */
|
|
131
|
+
static readonly conflict: (args: {
|
|
132
|
+
details: {
|
|
133
|
+
value: string;
|
|
134
|
+
key: string;
|
|
135
|
+
cause: string;
|
|
136
|
+
}[];
|
|
64
137
|
message?: string;
|
|
65
|
-
})
|
|
66
|
-
|
|
138
|
+
}) => ElevaError<BASE_ERROR_CODES.CONFLICT>;
|
|
139
|
+
/** HTTP 410 — resource permanently removed; retrying will never succeed. */
|
|
140
|
+
static readonly gone: (args?: {
|
|
67
141
|
message?: string;
|
|
68
|
-
details?:
|
|
69
|
-
|
|
70
|
-
|
|
142
|
+
details?: {
|
|
143
|
+
since?: string | undefined;
|
|
144
|
+
} | undefined;
|
|
145
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.GONE>;
|
|
146
|
+
/** HTTP 422 — request is syntactically valid but semantically unprocessable. */
|
|
147
|
+
static readonly unprocessableEntity: (args?: {
|
|
71
148
|
message?: string;
|
|
72
|
-
details?:
|
|
73
|
-
|
|
74
|
-
|
|
149
|
+
details?: {
|
|
150
|
+
field?: string | undefined;
|
|
151
|
+
reason?: string | undefined;
|
|
152
|
+
} | undefined;
|
|
153
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.UNPROCESSABLE_ENTITY>;
|
|
154
|
+
/**
|
|
155
|
+
* HTTP 502 — upstream service returned an invalid response (`SYSTEM`).
|
|
156
|
+
* @param args.details.upstream - Name of the misbehaving upstream service.
|
|
157
|
+
*/
|
|
158
|
+
static readonly badGateway: (args?: {
|
|
75
159
|
message?: string;
|
|
76
|
-
details?:
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
160
|
+
details?: {
|
|
161
|
+
upstream?: string | undefined;
|
|
162
|
+
} | undefined;
|
|
163
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.BAD_GATEWAY>;
|
|
164
|
+
/** HTTP 503 — service temporarily unavailable (`SYSTEM`). Pass `retryAfter` (seconds) if known. */
|
|
165
|
+
static readonly serviceUnavailable: (args?: {
|
|
80
166
|
message?: string;
|
|
81
|
-
|
|
167
|
+
details?: {
|
|
168
|
+
retryAfter?: number | undefined;
|
|
169
|
+
} | undefined;
|
|
170
|
+
} | undefined) => ElevaError<BASE_ERROR_CODES.SERVICE_UNAVAILABLE>;
|
|
171
|
+
/**
|
|
172
|
+
* HTTP 400 — a required field was missing from the request.
|
|
173
|
+
* @param args.field - Name of the missing field.
|
|
174
|
+
*/
|
|
175
|
+
static readonly mandatoryField: (args: Record<"field", string> & {
|
|
176
|
+
message?: string;
|
|
177
|
+
}) => ElevaError<BASE_ERROR_CODES.MANDATORY_FIELD>;
|
|
178
|
+
/**
|
|
179
|
+
* HTTP 500 — unexpected server error (`SYSTEM`).
|
|
180
|
+
* Pass the original exception as `cause` to preserve the full stack chain for logging.
|
|
181
|
+
*/
|
|
82
182
|
static internal(args?: {
|
|
83
183
|
message?: string;
|
|
84
184
|
cause?: unknown;
|
|
85
185
|
details?: ErrorDetails<BASE_ERROR_CODES.INTERNAL_SERVER_ERROR>;
|
|
86
186
|
}): ElevaError<BASE_ERROR_CODES.INTERNAL_SERVER_ERROR>;
|
|
87
|
-
|
|
187
|
+
/**
|
|
188
|
+
* HTTP 403 — caller is not authorised to access the given contact person.
|
|
189
|
+
* @param args.details.contactId - UUID of the blocked contact.
|
|
190
|
+
*/
|
|
191
|
+
static readonly forbiddenContact: (args: {
|
|
192
|
+
details: {
|
|
193
|
+
contactId: string;
|
|
194
|
+
};
|
|
88
195
|
message?: string;
|
|
89
|
-
|
|
90
|
-
}): ElevaError<API_ERROR_CODES.FORBIDDEN_CONTACT>;
|
|
196
|
+
}) => ElevaError<API_ERROR_CODES>;
|
|
91
197
|
}
|
|
92
198
|
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAA+B,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAA;AACrF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/errors/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,11 @@ const catalog_1 = require("./catalog");
|
|
|
6
6
|
const catalog_types_1 = require("./catalog_types");
|
|
7
7
|
const catalog_base_1 = require("./catalog_base");
|
|
8
8
|
const catalog_api_1 = require("./catalog_api");
|
|
9
|
+
/**
|
|
10
|
+
* Permissive schema for parsing unknown error payloads. All fields except `code`
|
|
11
|
+
* are optional so malformed responses always produce a valid result.
|
|
12
|
+
* `errors` is the legacy name for `details` (kept for backwards compatibility).
|
|
13
|
+
*/
|
|
9
14
|
const errorSchema = zod_1.z.object({
|
|
10
15
|
code: zod_1.z.string(),
|
|
11
16
|
kind: zod_1.z.string().optional(),
|
|
@@ -15,8 +20,14 @@ const errorSchema = zod_1.z.object({
|
|
|
15
20
|
/** @deprecated Use `details` instead */
|
|
16
21
|
errors: zod_1.z.unknown().optional(),
|
|
17
22
|
});
|
|
23
|
+
/** Pre-computed set of all valid error code strings for O(1) membership checks. */
|
|
18
24
|
const KNOWN_CODES = new Set(Object.keys(catalog_1.ERROR_CODES));
|
|
25
|
+
/** Pre-computed set of all valid `ErrorKind` values for O(1) membership checks. */
|
|
19
26
|
const VALID_KINDS = new Set(Object.values(catalog_types_1.ErrorKind));
|
|
27
|
+
/**
|
|
28
|
+
* Looks up the catalog entry for `code` and builds an `ElevaError`.
|
|
29
|
+
* Module-private — use the static factory methods on `ElevaError` instead.
|
|
30
|
+
*/
|
|
20
31
|
const _newElevaErrorFromCode = (code, args) => {
|
|
21
32
|
const entry = catalog_1.ERRORS_CATALOG[code];
|
|
22
33
|
return new ElevaError({
|
|
@@ -28,10 +39,53 @@ const _newElevaErrorFromCode = (code, args) => {
|
|
|
28
39
|
cause: args.cause,
|
|
29
40
|
});
|
|
30
41
|
};
|
|
42
|
+
/**
|
|
43
|
+
* Factory for codes whose `details` are entirely optional (every field is `.partial()`).
|
|
44
|
+
* Returns a function with signature `(args?: { message?, details? }) => ElevaError<C>`.
|
|
45
|
+
*/
|
|
46
|
+
const _optionalFactory = (code) => {
|
|
47
|
+
return (args = {}) => _newElevaErrorFromCode(code, { details: args.details ?? {}, message: args.message });
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Factory for codes where `details` is built from a single required string argument.
|
|
51
|
+
* The argument key mirrors the `details` key (e.g. `'entity'` → `{ entity }`).
|
|
52
|
+
*/
|
|
53
|
+
const _namedFieldFactory = (code, key) => {
|
|
54
|
+
return (args) => _newElevaErrorFromCode(code, { details: { [key]: args[key] }, message: args.message });
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Factory for codes where `details` is required and passed through directly.
|
|
58
|
+
* Returns a function with signature `(args: { details, message? }) => ElevaError<C>`.
|
|
59
|
+
*/
|
|
60
|
+
const _requiredDetailsFactory = (code) => {
|
|
61
|
+
return (args) => _newElevaErrorFromCode(code, { details: args.details, message: args.message });
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Central error class for the Eleva ERP SDK.
|
|
65
|
+
*
|
|
66
|
+
* Extends `Error` with structured metadata: `code`, `kind`, `status`, and typed `details`.
|
|
67
|
+
*
|
|
68
|
+
* ```ts
|
|
69
|
+
* // Create
|
|
70
|
+
* throw ElevaError.notFound({ entity: 'Invoice' })
|
|
71
|
+
* throw ElevaError.conflict({ details: [{ key: 'email', value: 'a@b.com', cause: 'duplicate' }] })
|
|
72
|
+
*
|
|
73
|
+
* // Narrow
|
|
74
|
+
* if (err instanceof ElevaError && err.is(ERROR_CODES.NOT_FOUND)) {
|
|
75
|
+
* console.log(err.details.entity) // string
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*
|
|
79
|
+
* Serialisation: `toJSON()` for logging, `toResponse()` for sanitised API output.
|
|
80
|
+
*/
|
|
31
81
|
class ElevaError extends Error {
|
|
82
|
+
/** Error code constant identifying the failure condition. */
|
|
32
83
|
code;
|
|
84
|
+
/** `DOMAIN` (safe to expose) or `SYSTEM` (sanitised before sending to clients). */
|
|
33
85
|
kind;
|
|
86
|
+
/** HTTP status code for this error. */
|
|
34
87
|
status;
|
|
88
|
+
/** Structured, code-specific failure context. */
|
|
35
89
|
details;
|
|
36
90
|
constructor(args) {
|
|
37
91
|
super(args.message, { cause: args.cause });
|
|
@@ -40,13 +94,21 @@ class ElevaError extends Error {
|
|
|
40
94
|
this.kind = args.kind;
|
|
41
95
|
this.status = args.status;
|
|
42
96
|
this.details = args.details;
|
|
97
|
+
// Removes the constructor frame from V8 stack traces.
|
|
43
98
|
if (Error.captureStackTrace) {
|
|
44
99
|
Error.captureStackTrace(this, this.constructor);
|
|
45
100
|
}
|
|
46
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Type-guard: narrows to `ElevaError<K>` when `this.code === code`.
|
|
104
|
+
* After a positive check `this.details` is fully typed for `K`.
|
|
105
|
+
* @example
|
|
106
|
+
* if (err.is(ERROR_CODES.NOT_FOUND)) console.log(err.details.entity)
|
|
107
|
+
*/
|
|
47
108
|
is(code) {
|
|
48
109
|
return this.code === code;
|
|
49
110
|
}
|
|
111
|
+
/** Full serialised representation for logging / diagnostics. */
|
|
50
112
|
toJSON() {
|
|
51
113
|
return {
|
|
52
114
|
code: this.code,
|
|
@@ -57,8 +119,12 @@ class ElevaError extends Error {
|
|
|
57
119
|
};
|
|
58
120
|
}
|
|
59
121
|
toString() {
|
|
60
|
-
return JSON.stringify(this
|
|
122
|
+
return JSON.stringify(this);
|
|
61
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Sanitised payload safe for API responses.
|
|
126
|
+
* `SYSTEM` errors replace the message with a generic string; `DOMAIN` errors include `details`.
|
|
127
|
+
*/
|
|
62
128
|
toResponse() {
|
|
63
129
|
const resp = {
|
|
64
130
|
code: this.code,
|
|
@@ -67,11 +133,18 @@ class ElevaError extends Error {
|
|
|
67
133
|
if (this.kind === catalog_types_1.ErrorKind.SYSTEM) {
|
|
68
134
|
resp.message = 'Houston, we have a problem';
|
|
69
135
|
}
|
|
70
|
-
if (this.kind === catalog_types_1.ErrorKind.DOMAIN) {
|
|
136
|
+
else if (this.kind === catalog_types_1.ErrorKind.DOMAIN) {
|
|
71
137
|
resp.details = this.details;
|
|
72
138
|
}
|
|
73
139
|
return resp;
|
|
74
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Parses an unknown value into `ElevaErrorArgs`. Shared by `parse()` and `RemoteElevaError.from()`.
|
|
143
|
+
*
|
|
144
|
+
* Strategy: validate against `errorSchema` → look up known codes in the catalog →
|
|
145
|
+
* fall back to `INTERNAL_SERVER_ERROR` for unrecognised codes or malformed payloads →
|
|
146
|
+
* accept legacy `errors` field as a fallback for `details`.
|
|
147
|
+
*/
|
|
75
148
|
static _parsePayload(value) {
|
|
76
149
|
const result = errorSchema.safeParse(value);
|
|
77
150
|
if (!result.success) {
|
|
@@ -98,90 +171,65 @@ class ElevaError extends Error {
|
|
|
98
171
|
details: (result.data.details ?? result.data.errors ?? {}),
|
|
99
172
|
};
|
|
100
173
|
}
|
|
174
|
+
/** Deserialises an unknown value into an `ElevaError`. Unrecognised payloads become `INTERNAL_SERVER_ERROR`. */
|
|
101
175
|
static parse(value) {
|
|
102
176
|
return new ElevaError(ElevaError._parsePayload(value));
|
|
103
177
|
}
|
|
178
|
+
/** Converts a `ZodError` into a `VALIDATION` error, preserving field paths and rule codes. */
|
|
104
179
|
static fromZodError(error) {
|
|
105
180
|
const errors = error.issues.map((issue) => {
|
|
106
181
|
const path = issue.path.map(String);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
code: issue.code,
|
|
110
|
-
message: issue.message,
|
|
111
|
-
path,
|
|
112
|
-
};
|
|
182
|
+
const validation = path.join('.') || 'root';
|
|
183
|
+
return { validation, code: issue.code, message: issue.message, path };
|
|
113
184
|
});
|
|
114
185
|
return ElevaError.validation({ errors, message: error.message });
|
|
115
186
|
}
|
|
187
|
+
/** Creates a `VALIDATION` error from a pre-built array of issue descriptors. */
|
|
116
188
|
static validation(args) {
|
|
117
189
|
return _newElevaErrorFromCode(catalog_base_1.BASE_ERROR_CODES.VALIDATION, {
|
|
118
190
|
details: { errors: args.errors },
|
|
119
191
|
message: args.message,
|
|
120
192
|
});
|
|
121
193
|
}
|
|
194
|
+
/** Creates a `VALIDATION` error for a single invalid field. Convenience wrapper around `validation()`. */
|
|
122
195
|
static invalidField(args) {
|
|
123
196
|
return ElevaError.validation({ errors: [args.error], message: args.message });
|
|
124
197
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
static
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
static
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
static
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
static gone(args = {}) {
|
|
162
|
-
return _newElevaErrorFromCode(catalog_base_1.BASE_ERROR_CODES.GONE, {
|
|
163
|
-
details: args.details ?? {},
|
|
164
|
-
message: args.message,
|
|
165
|
-
});
|
|
166
|
-
}
|
|
167
|
-
static unprocessableEntity(args = {}) {
|
|
168
|
-
return _newElevaErrorFromCode(catalog_base_1.BASE_ERROR_CODES.UNPROCESSABLE_ENTITY, {
|
|
169
|
-
details: args.details ?? {},
|
|
170
|
-
message: args.message,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
static serviceUnavailable(args = {}) {
|
|
174
|
-
return _newElevaErrorFromCode(catalog_base_1.BASE_ERROR_CODES.SERVICE_UNAVAILABLE, {
|
|
175
|
-
details: args.details ?? {},
|
|
176
|
-
message: args.message,
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
static mandatoryField(args) {
|
|
180
|
-
return _newElevaErrorFromCode(catalog_base_1.BASE_ERROR_CODES.MANDATORY_FIELD, {
|
|
181
|
-
details: { field: args.field },
|
|
182
|
-
message: args.message,
|
|
183
|
-
});
|
|
184
|
-
}
|
|
198
|
+
/** HTTP 400 — request is malformed or has invalid parameters outside of validation. */
|
|
199
|
+
static badRequest = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.BAD_REQUEST);
|
|
200
|
+
/** HTTP 401 — credentials are missing, expired, or invalid. Caller must re-authenticate. */
|
|
201
|
+
static authentication = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.AUTHENTICATION);
|
|
202
|
+
/** HTTP 403 — authenticated but lacks the required scope or permission. */
|
|
203
|
+
static unauthorized = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.UNAUTHORIZED);
|
|
204
|
+
/**
|
|
205
|
+
* HTTP 404 — no resource found for the given identifier.
|
|
206
|
+
* @param args.entity - Entity type that was not found (e.g. `"Invoice"`).
|
|
207
|
+
*/
|
|
208
|
+
static notFound = _namedFieldFactory(catalog_base_1.BASE_ERROR_CODES.NOT_FOUND, 'entity');
|
|
209
|
+
/** HTTP 406 — server cannot produce a response matching the `Accept` header. */
|
|
210
|
+
static notAcceptable = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.NOT_ACCEPTABLE);
|
|
211
|
+
/** HTTP 409 — operation violates a uniqueness or integrity constraint. */
|
|
212
|
+
static conflict = _requiredDetailsFactory(catalog_base_1.BASE_ERROR_CODES.CONFLICT);
|
|
213
|
+
/** HTTP 410 — resource permanently removed; retrying will never succeed. */
|
|
214
|
+
static gone = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.GONE);
|
|
215
|
+
/** HTTP 422 — request is syntactically valid but semantically unprocessable. */
|
|
216
|
+
static unprocessableEntity = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.UNPROCESSABLE_ENTITY);
|
|
217
|
+
/**
|
|
218
|
+
* HTTP 502 — upstream service returned an invalid response (`SYSTEM`).
|
|
219
|
+
* @param args.details.upstream - Name of the misbehaving upstream service.
|
|
220
|
+
*/
|
|
221
|
+
static badGateway = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.BAD_GATEWAY);
|
|
222
|
+
/** HTTP 503 — service temporarily unavailable (`SYSTEM`). Pass `retryAfter` (seconds) if known. */
|
|
223
|
+
static serviceUnavailable = _optionalFactory(catalog_base_1.BASE_ERROR_CODES.SERVICE_UNAVAILABLE);
|
|
224
|
+
/**
|
|
225
|
+
* HTTP 400 — a required field was missing from the request.
|
|
226
|
+
* @param args.field - Name of the missing field.
|
|
227
|
+
*/
|
|
228
|
+
static mandatoryField = _namedFieldFactory(catalog_base_1.BASE_ERROR_CODES.MANDATORY_FIELD, 'field');
|
|
229
|
+
/**
|
|
230
|
+
* HTTP 500 — unexpected server error (`SYSTEM`).
|
|
231
|
+
* Pass the original exception as `cause` to preserve the full stack chain for logging.
|
|
232
|
+
*/
|
|
185
233
|
static internal(args = {}) {
|
|
186
234
|
return _newElevaErrorFromCode(catalog_base_1.BASE_ERROR_CODES.INTERNAL_SERVER_ERROR, {
|
|
187
235
|
details: args.details ?? {},
|
|
@@ -189,12 +237,11 @@ class ElevaError extends Error {
|
|
|
189
237
|
cause: args.cause,
|
|
190
238
|
});
|
|
191
239
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
240
|
+
/**
|
|
241
|
+
* HTTP 403 — caller is not authorised to access the given contact person.
|
|
242
|
+
* @param args.details.contactId - UUID of the blocked contact.
|
|
243
|
+
*/
|
|
244
|
+
static forbiddenContact = _requiredDetailsFactory(catalog_api_1.API_ERROR_CODES.FORBIDDEN_CONTACT);
|
|
198
245
|
}
|
|
199
246
|
exports.ElevaError = ElevaError;
|
|
200
247
|
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/errors/errors.ts"],"names":[],"mappings":";;;AAAA,6BAAuB;AACvB,uCAAqF;AACrF,mDAA2C;AAC3C,iDAAiD;AACjD,+CAA+C;AAE/C,MAAM,WAAW,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC3B,MAAM,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC7B,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC9B,OAAO,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;IAC/B,wCAAwC;IACxC,MAAM,EAAE,OAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAA;AAEF,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAW,CAAC,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/errors/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -70,6 +70,18 @@ describe('ElevaError', () => {
|
|
|
70
70
|
const entity = err.is(_1.ERROR_CODES.NOT_FOUND) ? err.details.entity : null;
|
|
71
71
|
expect(entity).toBe('User');
|
|
72
72
|
});
|
|
73
|
+
it('returns true when a plain string matches the code', () => {
|
|
74
|
+
const error = _1.ElevaError.notFound(notFoundDetails);
|
|
75
|
+
expect(error.is('NOT_FOUND')).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
it('returns false when a plain string does not match the code', () => {
|
|
78
|
+
const error = _1.ElevaError.notFound(notFoundDetails);
|
|
79
|
+
expect(error.is('CONFLICT')).toBe(false);
|
|
80
|
+
});
|
|
81
|
+
it('returns true for uncatalogued codes matched by string', () => {
|
|
82
|
+
const error = _1.ElevaError.parse({ code: 'CUSTOM_CODE', message: 'custom' });
|
|
83
|
+
expect(error.is('CUSTOM_CODE')).toBe(true);
|
|
84
|
+
});
|
|
73
85
|
});
|
|
74
86
|
describe('toJSON() / toString()', () => {
|
|
75
87
|
it('toJSON returns a plain object with all fields', () => {
|