@bombillazo/error-x 0.5.1 → 0.6.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/README.md +173 -21
- package/dist/index.cjs +216 -124
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +222 -156
- package/dist/index.d.ts +222 -156
- package/dist/index.js +213 -125
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -58,8 +58,6 @@ type ErrorXOptions<TMetadata extends ErrorXMetadata = ErrorXMetadata> = {
|
|
|
58
58
|
name?: string;
|
|
59
59
|
/** Error identifier code (auto-generated from name if not provided) */
|
|
60
60
|
code?: string | number;
|
|
61
|
-
/** User-friendly message for UI display */
|
|
62
|
-
uiMessage?: string | undefined;
|
|
63
61
|
/** Original error that caused this error (preserves error chain, will be converted to ErrorXSnapshot format) */
|
|
64
62
|
cause?: unknown;
|
|
65
63
|
/** Additional context and debugging information */
|
|
@@ -82,51 +80,155 @@ type ErrorXSnapshot = {
|
|
|
82
80
|
stack?: string;
|
|
83
81
|
};
|
|
84
82
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
83
|
+
* Type representing valid preset keys for error creation.
|
|
84
|
+
* Allows both string and number keys while preventing accidental misuse.
|
|
87
85
|
*
|
|
88
86
|
* @public
|
|
89
87
|
*/
|
|
90
|
-
type
|
|
91
|
-
|
|
92
|
-
presetKey: string | number | undefined;
|
|
93
|
-
};
|
|
88
|
+
type ErrorXBasePresetKey = (number & {}) | (string & {});
|
|
89
|
+
|
|
94
90
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
91
|
+
* Base configuration properties provided by error-x.
|
|
92
|
+
* Users extend this with their custom properties via ErrorXResolverConfig.
|
|
97
93
|
*
|
|
98
94
|
* @public
|
|
99
95
|
*/
|
|
100
|
-
type
|
|
96
|
+
type ErrorXBaseConfig = {
|
|
97
|
+
/** i18n namespace for translation key resolution (e.g., 'errors.api') */
|
|
98
|
+
namespace: string;
|
|
99
|
+
/** Path appended to docs base URL (e.g., '/api') */
|
|
100
|
+
docsPath?: string;
|
|
101
|
+
/** Static UI message - overrides i18n at preset level, fallback otherwise */
|
|
102
|
+
uiMessage?: string;
|
|
103
|
+
};
|
|
101
104
|
/**
|
|
102
|
-
*
|
|
103
|
-
* Used for transmitting errors over network or storing in databases.
|
|
105
|
+
* Type helper combining ErrorXBaseConfig with user's custom config properties.
|
|
104
106
|
*
|
|
105
107
|
* @example
|
|
106
108
|
* ```typescript
|
|
107
|
-
*
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
* uiMessage: 'Please check your credentials',
|
|
112
|
-
* stack: 'Error: Authentication failed.\n at login (auth.ts:42:15)',
|
|
113
|
-
* metadata: { userId: 123, loginAttempt: 3 },
|
|
114
|
-
* timestamp: 1705315845123,
|
|
115
|
-
* httpStatus: 401,
|
|
116
|
-
* original: {
|
|
117
|
-
* name: 'NetworkError',
|
|
118
|
-
* message: 'Request timeout.',
|
|
119
|
-
* stack: '...'
|
|
120
|
-
* },
|
|
121
|
-
* chain: [
|
|
122
|
-
* { name: 'AuthError', message: 'Authentication failed.' },
|
|
123
|
-
* { name: 'NetworkError', message: 'Request timeout.' }
|
|
124
|
-
* ]
|
|
125
|
-
* }
|
|
109
|
+
* type MyConfig = ErrorXResolverConfig<{
|
|
110
|
+
* severity: 'error' | 'warning' | 'info';
|
|
111
|
+
* retryable: boolean;
|
|
112
|
+
* }>;
|
|
126
113
|
* ```
|
|
127
114
|
*
|
|
128
115
|
* @public
|
|
129
116
|
*/
|
|
117
|
+
type ErrorXResolverConfig<TCustom extends Record<string, unknown> = Record<string, unknown>> = ErrorXBaseConfig & TCustom;
|
|
118
|
+
/**
|
|
119
|
+
* Context object passed to the onResolve callback.
|
|
120
|
+
* Contains computed values and merged config for the error.
|
|
121
|
+
*
|
|
122
|
+
* @public
|
|
123
|
+
*/
|
|
124
|
+
type ResolveContext<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig> = {
|
|
125
|
+
/** Resolved UI message (from i18n or static config) */
|
|
126
|
+
uiMessage: string | undefined;
|
|
127
|
+
/** Full documentation URL */
|
|
128
|
+
docsUrl: string;
|
|
129
|
+
/** The resolved i18n key (e.g., 'errors.api.AUTH_EXPIRED') */
|
|
130
|
+
i18nKey: string;
|
|
131
|
+
/** The error type returned by onResolveType callback */
|
|
132
|
+
errorType: string;
|
|
133
|
+
/** Merged config for this error (defaults + type + preset) */
|
|
134
|
+
config: TConfig;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* i18n configuration for the resolver.
|
|
138
|
+
*
|
|
139
|
+
* @public
|
|
140
|
+
*/
|
|
141
|
+
type ErrorXResolverI18nConfig = {
|
|
142
|
+
/**
|
|
143
|
+
* User-provided translation function.
|
|
144
|
+
* Receives the i18n key and optional interpolation params (from error.metadata).
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* ```typescript
|
|
148
|
+
* resolver: (key, params) => i18next.t(key, params)
|
|
149
|
+
* ```
|
|
150
|
+
*/
|
|
151
|
+
resolver: (key: string, params?: Record<string, unknown>) => string;
|
|
152
|
+
/**
|
|
153
|
+
* Template for building translation keys.
|
|
154
|
+
* Available placeholders: {namespace}, {code}, {name}, {errorType}
|
|
155
|
+
* @default '{namespace}.{code}'
|
|
156
|
+
*/
|
|
157
|
+
keyTemplate?: string;
|
|
158
|
+
};
|
|
159
|
+
/**
|
|
160
|
+
* Documentation configuration for the resolver.
|
|
161
|
+
*
|
|
162
|
+
* @public
|
|
163
|
+
*/
|
|
164
|
+
type ErrorXResolverDocsConfig = {
|
|
165
|
+
/**
|
|
166
|
+
* Base URL for documentation.
|
|
167
|
+
* @default '' (empty string)
|
|
168
|
+
*/
|
|
169
|
+
baseUrl?: string;
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* Per-error-type configuration with optional preset overrides.
|
|
173
|
+
*
|
|
174
|
+
* @public
|
|
175
|
+
*/
|
|
176
|
+
type ErrorXResolverTypeConfig<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig> = Omit<TConfig, 'presets'> & {
|
|
177
|
+
/** Per-error-code overrides within this type */
|
|
178
|
+
presets?: {
|
|
179
|
+
[code: string]: Partial<ErrorXBaseConfig> & Partial<Omit<TConfig, keyof ErrorXBaseConfig>>;
|
|
180
|
+
};
|
|
181
|
+
};
|
|
182
|
+
/**
|
|
183
|
+
* Full configuration options for ErrorXResolver.
|
|
184
|
+
*
|
|
185
|
+
* @public
|
|
186
|
+
*/
|
|
187
|
+
type ErrorXResolverOptions<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig, TResult = ResolveContext<TConfig>> = {
|
|
188
|
+
/** Optional i18n configuration. If not provided, relies on static uiMessage values. */
|
|
189
|
+
i18n?: ErrorXResolverI18nConfig;
|
|
190
|
+
/** Optional documentation URL configuration. */
|
|
191
|
+
docs?: ErrorXResolverDocsConfig;
|
|
192
|
+
/**
|
|
193
|
+
* Callback to determine the error type key.
|
|
194
|
+
* The returned string is used to look up config in the configs object.
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* onResolveType: (error) => {
|
|
199
|
+
* if (error instanceof APIErrorX) return 'api';
|
|
200
|
+
* if (error.code.startsWith('DB_')) return 'database';
|
|
201
|
+
* return 'general';
|
|
202
|
+
* }
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
onResolveType: (error: ErrorX) => string;
|
|
206
|
+
/**
|
|
207
|
+
* Optional callback to customize the resolve output.
|
|
208
|
+
* If not provided, resolve() returns the ResolveContext directly.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```typescript
|
|
212
|
+
* onResolve: (error, context) => ({
|
|
213
|
+
* message: context.uiMessage,
|
|
214
|
+
* docs: context.docsUrl,
|
|
215
|
+
* severity: context.config.severity,
|
|
216
|
+
* })
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
onResolve?: (error: ErrorX, context: ResolveContext<TConfig>) => TResult;
|
|
220
|
+
/** Default config values (fallback for all error types) */
|
|
221
|
+
defaults?: Partial<ErrorXBaseConfig> & Partial<Omit<TConfig, keyof ErrorXBaseConfig>>;
|
|
222
|
+
/** Per-error-type configurations (partial configs get merged with defaults) */
|
|
223
|
+
configs: Record<string, Partial<ErrorXResolverTypeConfig<TConfig>>>;
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* JSON-serializable representation of an ErrorX instance.
|
|
228
|
+
* Used for transmitting errors over network or storing in databases.
|
|
229
|
+
*
|
|
230
|
+
* @public
|
|
231
|
+
*/
|
|
130
232
|
type ErrorXSerialized = {
|
|
131
233
|
/** Error type/name */
|
|
132
234
|
name: string;
|
|
@@ -134,8 +236,6 @@ type ErrorXSerialized = {
|
|
|
134
236
|
message: string;
|
|
135
237
|
/** Error identifier code */
|
|
136
238
|
code: string;
|
|
137
|
-
/** User-friendly message for UI display */
|
|
138
|
-
uiMessage: string | undefined;
|
|
139
239
|
/** Stack trace (optional) */
|
|
140
240
|
stack?: string;
|
|
141
241
|
/** Additional context and debugging information */
|
|
@@ -149,13 +249,24 @@ type ErrorXSerialized = {
|
|
|
149
249
|
/** Serialized error chain timeline (this error and all ancestors) */
|
|
150
250
|
chain?: ErrorXSerialized[];
|
|
151
251
|
};
|
|
252
|
+
|
|
152
253
|
/**
|
|
153
|
-
*
|
|
154
|
-
*
|
|
254
|
+
* Context passed to the transform function when creating errors via `.create()`.
|
|
255
|
+
* Contains information about the preset being used.
|
|
155
256
|
*
|
|
156
257
|
* @public
|
|
157
258
|
*/
|
|
158
|
-
type
|
|
259
|
+
type ErrorXTransformContext = {
|
|
260
|
+
/** The preset key used (if any) */
|
|
261
|
+
presetKey: string | number | undefined;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* Transform function signature for custom error classes.
|
|
265
|
+
* Transforms options after merge but before instantiation.
|
|
266
|
+
*
|
|
267
|
+
* @public
|
|
268
|
+
*/
|
|
269
|
+
type ErrorXTransform<TMetadata extends ErrorXMetadata = ErrorXMetadata> = (opts: ErrorXOptions<ErrorXMetadata>, ctx: ErrorXTransformContext) => ErrorXOptions<TMetadata>;
|
|
159
270
|
|
|
160
271
|
/**
|
|
161
272
|
* Configuration interface for ErrorX global settings
|
|
@@ -194,7 +305,6 @@ interface ErrorXConfig {
|
|
|
194
305
|
* message: 'User authentication failed',
|
|
195
306
|
* name: 'AuthError',
|
|
196
307
|
* code: 'AUTH_FAILED',
|
|
197
|
-
* uiMessage: 'Please check your credentials',
|
|
198
308
|
* metadata: { userId: 123, loginAttempt: 3 }
|
|
199
309
|
* })
|
|
200
310
|
*
|
|
@@ -214,8 +324,6 @@ declare class ErrorX<TMetadata extends ErrorXMetadata = ErrorXMetadata> extends
|
|
|
214
324
|
private static _config;
|
|
215
325
|
/** Error identifier code, auto-generated from name if not provided */
|
|
216
326
|
code: string;
|
|
217
|
-
/** User-friendly message suitable for display in UI */
|
|
218
|
-
uiMessage: string | undefined;
|
|
219
327
|
/** Additional context and metadata associated with the error */
|
|
220
328
|
metadata: TMetadata | undefined;
|
|
221
329
|
/** Unix epoch timestamp (milliseconds) when the error was created */
|
|
@@ -259,7 +367,6 @@ declare class ErrorX<TMetadata extends ErrorXMetadata = ErrorXMetadata> extends
|
|
|
259
367
|
* message: 'Database query failed',
|
|
260
368
|
* name: 'DatabaseError',
|
|
261
369
|
* code: 'DB_QUERY_FAILED',
|
|
262
|
-
* uiMessage: 'Unable to load data. Please try again.',
|
|
263
370
|
* metadata: { query: 'SELECT * FROM users', timeout: 5000 }
|
|
264
371
|
* })
|
|
265
372
|
*
|
|
@@ -505,7 +612,6 @@ declare class ErrorX<TMetadata extends ErrorXMetadata = ErrorXMetadata> extends
|
|
|
505
612
|
* name: 'DatabaseError',
|
|
506
613
|
* message: 'Connection failed.',
|
|
507
614
|
* code: 'DB_CONN_FAILED',
|
|
508
|
-
* uiMessage: 'Database is temporarily unavailable',
|
|
509
615
|
* metadata: { host: 'localhost' },
|
|
510
616
|
* timestamp: 1705315845123
|
|
511
617
|
* }
|
|
@@ -571,99 +677,89 @@ declare const dbPresets: {
|
|
|
571
677
|
readonly code: "CONNECTION_FAILED";
|
|
572
678
|
readonly name: "DBConnectionError";
|
|
573
679
|
readonly message: "Failed to connect to database.";
|
|
574
|
-
readonly uiMessage: "Unable to connect to the database. Please try again later.";
|
|
575
680
|
};
|
|
576
681
|
readonly CONNECTION_TIMEOUT: {
|
|
577
682
|
readonly code: "CONNECTION_TIMEOUT";
|
|
578
683
|
readonly name: "DBConnectionTimeoutError";
|
|
579
684
|
readonly message: "Database connection timed out.";
|
|
580
|
-
readonly uiMessage: "The database connection timed out. Please try again.";
|
|
581
685
|
};
|
|
582
686
|
readonly CONNECTION_REFUSED: {
|
|
583
687
|
readonly code: "CONNECTION_REFUSED";
|
|
584
688
|
readonly name: "DBConnectionRefusedError";
|
|
585
689
|
readonly message: "Database connection refused.";
|
|
586
|
-
readonly uiMessage: "Unable to connect to the database. Please try again later.";
|
|
587
690
|
};
|
|
588
691
|
readonly CONNECTION_LOST: {
|
|
589
692
|
readonly code: "CONNECTION_LOST";
|
|
590
693
|
readonly name: "DBConnectionLostError";
|
|
591
694
|
readonly message: "Database connection lost.";
|
|
592
|
-
readonly uiMessage: "The database connection was lost. Please try again.";
|
|
593
695
|
};
|
|
594
696
|
readonly QUERY_FAILED: {
|
|
595
697
|
readonly code: "QUERY_FAILED";
|
|
596
698
|
readonly name: "DBQueryError";
|
|
597
699
|
readonly message: "Database query failed.";
|
|
598
|
-
readonly uiMessage: "The database operation failed. Please try again.";
|
|
599
700
|
};
|
|
600
701
|
readonly QUERY_TIMEOUT: {
|
|
601
702
|
readonly code: "QUERY_TIMEOUT";
|
|
602
703
|
readonly name: "DBQueryTimeoutError";
|
|
603
704
|
readonly message: "Database query timed out.";
|
|
604
|
-
readonly uiMessage: "The database operation took too long. Please try again.";
|
|
605
705
|
};
|
|
606
706
|
readonly SYNTAX_ERROR: {
|
|
607
707
|
readonly code: "SYNTAX_ERROR";
|
|
608
708
|
readonly name: "DBSyntaxError";
|
|
609
709
|
readonly message: "Invalid query syntax.";
|
|
610
|
-
readonly uiMessage: "An internal error occurred. Please contact support.";
|
|
611
710
|
};
|
|
612
711
|
readonly UNIQUE_VIOLATION: {
|
|
613
712
|
readonly code: "UNIQUE_VIOLATION";
|
|
614
713
|
readonly name: "DBUniqueViolationError";
|
|
615
714
|
readonly message: "Unique constraint violation.";
|
|
616
|
-
readonly uiMessage: "This record already exists.";
|
|
617
715
|
readonly httpStatus: 409;
|
|
618
716
|
};
|
|
619
717
|
readonly FOREIGN_KEY_VIOLATION: {
|
|
620
718
|
readonly code: "FOREIGN_KEY_VIOLATION";
|
|
621
719
|
readonly name: "DBForeignKeyError";
|
|
622
720
|
readonly message: "Foreign key constraint violation.";
|
|
623
|
-
readonly uiMessage: "This operation references a record that does not exist.";
|
|
624
721
|
readonly httpStatus: 400;
|
|
625
722
|
};
|
|
626
723
|
readonly NOT_NULL_VIOLATION: {
|
|
627
724
|
readonly code: "NOT_NULL_VIOLATION";
|
|
628
725
|
readonly name: "DBNotNullError";
|
|
629
726
|
readonly message: "Not null constraint violation.";
|
|
630
|
-
readonly uiMessage: "A required field is missing.";
|
|
631
727
|
readonly httpStatus: 400;
|
|
632
728
|
};
|
|
633
729
|
readonly CHECK_VIOLATION: {
|
|
634
730
|
readonly code: "CHECK_VIOLATION";
|
|
635
731
|
readonly name: "DBCheckViolationError";
|
|
636
732
|
readonly message: "Check constraint violation.";
|
|
637
|
-
readonly uiMessage: "The provided data is invalid.";
|
|
638
733
|
readonly httpStatus: 400;
|
|
639
734
|
};
|
|
640
735
|
readonly TRANSACTION_FAILED: {
|
|
641
736
|
readonly code: "TRANSACTION_FAILED";
|
|
642
737
|
readonly name: "DBTransactionError";
|
|
643
738
|
readonly message: "Database transaction failed.";
|
|
644
|
-
readonly uiMessage: "The operation failed. Please try again.";
|
|
645
739
|
};
|
|
646
740
|
readonly DEADLOCK: {
|
|
647
741
|
readonly code: "DEADLOCK";
|
|
648
742
|
readonly name: "DBDeadlockError";
|
|
649
743
|
readonly message: "Database deadlock detected.";
|
|
650
|
-
readonly uiMessage: "The operation encountered a conflict. Please try again.";
|
|
651
744
|
readonly httpStatus: 409;
|
|
652
745
|
};
|
|
653
746
|
readonly NOT_FOUND: {
|
|
654
747
|
readonly code: "NOT_FOUND";
|
|
655
748
|
readonly name: "DBNotFoundError";
|
|
656
749
|
readonly message: "Record not found.";
|
|
657
|
-
readonly uiMessage: "The requested record was not found.";
|
|
658
750
|
readonly httpStatus: 404;
|
|
659
751
|
};
|
|
660
752
|
readonly UNKNOWN: {
|
|
661
753
|
readonly code: "UNKNOWN";
|
|
662
754
|
readonly name: "DBErrorX";
|
|
663
755
|
readonly message: "An unknown database error occurred.";
|
|
664
|
-
readonly uiMessage: "A database error occurred. Please try again later.";
|
|
665
756
|
};
|
|
666
757
|
};
|
|
758
|
+
/**
|
|
759
|
+
* User-friendly messages for database error presets.
|
|
760
|
+
* Keyed by preset name.
|
|
761
|
+
*/
|
|
762
|
+
declare const dbErrorUiMessages: Record<keyof typeof dbPresets, string>;
|
|
667
763
|
/**
|
|
668
764
|
* Valid preset keys for DBErrorX.create()
|
|
669
765
|
* Derived from the presets object. Provides autocomplete for known presets
|
|
@@ -745,97 +841,82 @@ declare class DBErrorX extends ErrorX<DBErrorXMetadata> {
|
|
|
745
841
|
readonly code: "CONNECTION_FAILED";
|
|
746
842
|
readonly name: "DBConnectionError";
|
|
747
843
|
readonly message: "Failed to connect to database.";
|
|
748
|
-
readonly uiMessage: "Unable to connect to the database. Please try again later.";
|
|
749
844
|
};
|
|
750
845
|
readonly CONNECTION_TIMEOUT: {
|
|
751
846
|
readonly code: "CONNECTION_TIMEOUT";
|
|
752
847
|
readonly name: "DBConnectionTimeoutError";
|
|
753
848
|
readonly message: "Database connection timed out.";
|
|
754
|
-
readonly uiMessage: "The database connection timed out. Please try again.";
|
|
755
849
|
};
|
|
756
850
|
readonly CONNECTION_REFUSED: {
|
|
757
851
|
readonly code: "CONNECTION_REFUSED";
|
|
758
852
|
readonly name: "DBConnectionRefusedError";
|
|
759
853
|
readonly message: "Database connection refused.";
|
|
760
|
-
readonly uiMessage: "Unable to connect to the database. Please try again later.";
|
|
761
854
|
};
|
|
762
855
|
readonly CONNECTION_LOST: {
|
|
763
856
|
readonly code: "CONNECTION_LOST";
|
|
764
857
|
readonly name: "DBConnectionLostError";
|
|
765
858
|
readonly message: "Database connection lost.";
|
|
766
|
-
readonly uiMessage: "The database connection was lost. Please try again.";
|
|
767
859
|
};
|
|
768
860
|
readonly QUERY_FAILED: {
|
|
769
861
|
readonly code: "QUERY_FAILED";
|
|
770
862
|
readonly name: "DBQueryError";
|
|
771
863
|
readonly message: "Database query failed.";
|
|
772
|
-
readonly uiMessage: "The database operation failed. Please try again.";
|
|
773
864
|
};
|
|
774
865
|
readonly QUERY_TIMEOUT: {
|
|
775
866
|
readonly code: "QUERY_TIMEOUT";
|
|
776
867
|
readonly name: "DBQueryTimeoutError";
|
|
777
868
|
readonly message: "Database query timed out.";
|
|
778
|
-
readonly uiMessage: "The database operation took too long. Please try again.";
|
|
779
869
|
};
|
|
780
870
|
readonly SYNTAX_ERROR: {
|
|
781
871
|
readonly code: "SYNTAX_ERROR";
|
|
782
872
|
readonly name: "DBSyntaxError";
|
|
783
873
|
readonly message: "Invalid query syntax.";
|
|
784
|
-
readonly uiMessage: "An internal error occurred. Please contact support.";
|
|
785
874
|
};
|
|
786
875
|
readonly UNIQUE_VIOLATION: {
|
|
787
876
|
readonly code: "UNIQUE_VIOLATION";
|
|
788
877
|
readonly name: "DBUniqueViolationError";
|
|
789
878
|
readonly message: "Unique constraint violation.";
|
|
790
|
-
readonly uiMessage: "This record already exists.";
|
|
791
879
|
readonly httpStatus: 409;
|
|
792
880
|
};
|
|
793
881
|
readonly FOREIGN_KEY_VIOLATION: {
|
|
794
882
|
readonly code: "FOREIGN_KEY_VIOLATION";
|
|
795
883
|
readonly name: "DBForeignKeyError";
|
|
796
884
|
readonly message: "Foreign key constraint violation.";
|
|
797
|
-
readonly uiMessage: "This operation references a record that does not exist.";
|
|
798
885
|
readonly httpStatus: 400;
|
|
799
886
|
};
|
|
800
887
|
readonly NOT_NULL_VIOLATION: {
|
|
801
888
|
readonly code: "NOT_NULL_VIOLATION";
|
|
802
889
|
readonly name: "DBNotNullError";
|
|
803
890
|
readonly message: "Not null constraint violation.";
|
|
804
|
-
readonly uiMessage: "A required field is missing.";
|
|
805
891
|
readonly httpStatus: 400;
|
|
806
892
|
};
|
|
807
893
|
readonly CHECK_VIOLATION: {
|
|
808
894
|
readonly code: "CHECK_VIOLATION";
|
|
809
895
|
readonly name: "DBCheckViolationError";
|
|
810
896
|
readonly message: "Check constraint violation.";
|
|
811
|
-
readonly uiMessage: "The provided data is invalid.";
|
|
812
897
|
readonly httpStatus: 400;
|
|
813
898
|
};
|
|
814
899
|
readonly TRANSACTION_FAILED: {
|
|
815
900
|
readonly code: "TRANSACTION_FAILED";
|
|
816
901
|
readonly name: "DBTransactionError";
|
|
817
902
|
readonly message: "Database transaction failed.";
|
|
818
|
-
readonly uiMessage: "The operation failed. Please try again.";
|
|
819
903
|
};
|
|
820
904
|
readonly DEADLOCK: {
|
|
821
905
|
readonly code: "DEADLOCK";
|
|
822
906
|
readonly name: "DBDeadlockError";
|
|
823
907
|
readonly message: "Database deadlock detected.";
|
|
824
|
-
readonly uiMessage: "The operation encountered a conflict. Please try again.";
|
|
825
908
|
readonly httpStatus: 409;
|
|
826
909
|
};
|
|
827
910
|
readonly NOT_FOUND: {
|
|
828
911
|
readonly code: "NOT_FOUND";
|
|
829
912
|
readonly name: "DBNotFoundError";
|
|
830
913
|
readonly message: "Record not found.";
|
|
831
|
-
readonly uiMessage: "The requested record was not found.";
|
|
832
914
|
readonly httpStatus: 404;
|
|
833
915
|
};
|
|
834
916
|
readonly UNKNOWN: {
|
|
835
917
|
readonly code: "UNKNOWN";
|
|
836
918
|
readonly name: "DBErrorX";
|
|
837
919
|
readonly message: "An unknown database error occurred.";
|
|
838
|
-
readonly uiMessage: "A database error occurred. Please try again later.";
|
|
839
920
|
};
|
|
840
921
|
};
|
|
841
922
|
/** Default to UNKNOWN when no preset specified */
|
|
@@ -868,237 +949,203 @@ declare const httpPresets: {
|
|
|
868
949
|
readonly code: "BAD_REQUEST";
|
|
869
950
|
readonly name: "BadRequestError";
|
|
870
951
|
readonly message: "Bad request.";
|
|
871
|
-
readonly uiMessage: "The request could not be processed. Please check your input and try again.";
|
|
872
952
|
};
|
|
873
953
|
readonly 401: {
|
|
874
954
|
readonly code: "UNAUTHORIZED";
|
|
875
955
|
readonly name: "UnauthorizedError";
|
|
876
956
|
readonly message: "Unauthorized.";
|
|
877
|
-
readonly uiMessage: "Authentication required. Please log in to continue.";
|
|
878
957
|
};
|
|
879
958
|
readonly 402: {
|
|
880
959
|
readonly code: "PAYMENT_REQUIRED";
|
|
881
960
|
readonly name: "PaymentRequiredError";
|
|
882
961
|
readonly message: "Payment required.";
|
|
883
|
-
readonly uiMessage: "Payment is required to access this resource.";
|
|
884
962
|
};
|
|
885
963
|
readonly 403: {
|
|
886
964
|
readonly code: "FORBIDDEN";
|
|
887
965
|
readonly name: "ForbiddenError";
|
|
888
966
|
readonly message: "Forbidden.";
|
|
889
|
-
readonly uiMessage: "You do not have permission to access this resource.";
|
|
890
967
|
};
|
|
891
968
|
readonly 404: {
|
|
892
969
|
readonly code: "NOT_FOUND";
|
|
893
970
|
readonly name: "NotFoundError";
|
|
894
971
|
readonly message: "Not found.";
|
|
895
|
-
readonly uiMessage: "The requested resource could not be found.";
|
|
896
972
|
};
|
|
897
973
|
readonly 405: {
|
|
898
974
|
readonly code: "METHOD_NOT_ALLOWED";
|
|
899
975
|
readonly name: "MethodNotAllowedError";
|
|
900
976
|
readonly message: "Method not allowed.";
|
|
901
|
-
readonly uiMessage: "This action is not allowed for the requested resource.";
|
|
902
977
|
};
|
|
903
978
|
readonly 406: {
|
|
904
979
|
readonly code: "NOT_ACCEPTABLE";
|
|
905
980
|
readonly name: "NotAcceptableError";
|
|
906
981
|
readonly message: "Not acceptable.";
|
|
907
|
-
readonly uiMessage: "The requested format is not supported.";
|
|
908
982
|
};
|
|
909
983
|
readonly 407: {
|
|
910
984
|
readonly code: "PROXY_AUTHENTICATION_REQUIRED";
|
|
911
985
|
readonly name: "ProxyAuthenticationRequiredError";
|
|
912
986
|
readonly message: "Proxy authentication required.";
|
|
913
|
-
readonly uiMessage: "Proxy authentication is required to access this resource.";
|
|
914
987
|
};
|
|
915
988
|
readonly 408: {
|
|
916
989
|
readonly code: "REQUEST_TIMEOUT";
|
|
917
990
|
readonly name: "RequestTimeoutError";
|
|
918
991
|
readonly message: "Request timeout.";
|
|
919
|
-
readonly uiMessage: "The request took too long to complete. Please try again.";
|
|
920
992
|
};
|
|
921
993
|
readonly 409: {
|
|
922
994
|
readonly code: "CONFLICT";
|
|
923
995
|
readonly name: "ConflictError";
|
|
924
996
|
readonly message: "Conflict.";
|
|
925
|
-
readonly uiMessage: "The request conflicts with the current state. Please refresh and try again.";
|
|
926
997
|
};
|
|
927
998
|
readonly 410: {
|
|
928
999
|
readonly code: "GONE";
|
|
929
1000
|
readonly name: "GoneError";
|
|
930
1001
|
readonly message: "Gone.";
|
|
931
|
-
readonly uiMessage: "This resource is no longer available.";
|
|
932
1002
|
};
|
|
933
1003
|
readonly 411: {
|
|
934
1004
|
readonly code: "LENGTH_REQUIRED";
|
|
935
1005
|
readonly name: "LengthRequiredError";
|
|
936
1006
|
readonly message: "Length required.";
|
|
937
|
-
readonly uiMessage: "The request is missing required length information.";
|
|
938
1007
|
};
|
|
939
1008
|
readonly 412: {
|
|
940
1009
|
readonly code: "PRECONDITION_FAILED";
|
|
941
1010
|
readonly name: "PreconditionFailedError";
|
|
942
1011
|
readonly message: "Precondition failed.";
|
|
943
|
-
readonly uiMessage: "A required condition was not met. Please try again.";
|
|
944
1012
|
};
|
|
945
1013
|
readonly 413: {
|
|
946
1014
|
readonly code: "PAYLOAD_TOO_LARGE";
|
|
947
1015
|
readonly name: "PayloadTooLargeError";
|
|
948
1016
|
readonly message: "Payload too large.";
|
|
949
|
-
readonly uiMessage: "The request is too large. Please reduce the size and try again.";
|
|
950
1017
|
};
|
|
951
1018
|
readonly 414: {
|
|
952
1019
|
readonly code: "URI_TOO_LONG";
|
|
953
1020
|
readonly name: "UriTooLongError";
|
|
954
1021
|
readonly message: "URI too long.";
|
|
955
|
-
readonly uiMessage: "The request URL is too long.";
|
|
956
1022
|
};
|
|
957
1023
|
readonly 415: {
|
|
958
1024
|
readonly code: "UNSUPPORTED_MEDIA_TYPE";
|
|
959
1025
|
readonly name: "UnsupportedMediaTypeError";
|
|
960
1026
|
readonly message: "Unsupported media type.";
|
|
961
|
-
readonly uiMessage: "The file type is not supported.";
|
|
962
1027
|
};
|
|
963
1028
|
readonly 416: {
|
|
964
1029
|
readonly code: "RANGE_NOT_SATISFIABLE";
|
|
965
1030
|
readonly name: "RangeNotSatisfiableError";
|
|
966
1031
|
readonly message: "Range not satisfiable.";
|
|
967
|
-
readonly uiMessage: "The requested range cannot be satisfied.";
|
|
968
1032
|
};
|
|
969
1033
|
readonly 417: {
|
|
970
1034
|
readonly code: "EXPECTATION_FAILED";
|
|
971
1035
|
readonly name: "ExpectationFailedError";
|
|
972
1036
|
readonly message: "Expectation failed.";
|
|
973
|
-
readonly uiMessage: "The server cannot meet the requirements of the request.";
|
|
974
1037
|
};
|
|
975
1038
|
readonly 418: {
|
|
976
1039
|
readonly code: "IM_A_TEAPOT";
|
|
977
1040
|
readonly name: "ImATeapotError";
|
|
978
1041
|
readonly message: "I'm a teapot.";
|
|
979
|
-
readonly uiMessage: "I'm a teapot and cannot brew coffee.";
|
|
980
1042
|
};
|
|
981
1043
|
readonly 422: {
|
|
982
1044
|
readonly code: "UNPROCESSABLE_ENTITY";
|
|
983
1045
|
readonly name: "UnprocessableEntityError";
|
|
984
1046
|
readonly message: "Unprocessable entity.";
|
|
985
|
-
readonly uiMessage: "The request contains invalid data. Please check your input.";
|
|
986
1047
|
};
|
|
987
1048
|
readonly 423: {
|
|
988
1049
|
readonly code: "LOCKED";
|
|
989
1050
|
readonly name: "LockedError";
|
|
990
1051
|
readonly message: "Locked.";
|
|
991
|
-
readonly uiMessage: "This resource is locked and cannot be modified.";
|
|
992
1052
|
};
|
|
993
1053
|
readonly 424: {
|
|
994
1054
|
readonly code: "FAILED_DEPENDENCY";
|
|
995
1055
|
readonly name: "FailedDependencyError";
|
|
996
1056
|
readonly message: "Failed dependency.";
|
|
997
|
-
readonly uiMessage: "The request failed due to a dependency error.";
|
|
998
1057
|
};
|
|
999
1058
|
readonly 425: {
|
|
1000
1059
|
readonly code: "TOO_EARLY";
|
|
1001
1060
|
readonly name: "TooEarlyError";
|
|
1002
1061
|
readonly message: "Too early.";
|
|
1003
|
-
readonly uiMessage: "The request was sent too early. Please try again later.";
|
|
1004
1062
|
};
|
|
1005
1063
|
readonly 426: {
|
|
1006
1064
|
readonly code: "UPGRADE_REQUIRED";
|
|
1007
1065
|
readonly name: "UpgradeRequiredError";
|
|
1008
1066
|
readonly message: "Upgrade required.";
|
|
1009
|
-
readonly uiMessage: "Please upgrade to continue using this service.";
|
|
1010
1067
|
};
|
|
1011
1068
|
readonly 428: {
|
|
1012
1069
|
readonly code: "PRECONDITION_REQUIRED";
|
|
1013
1070
|
readonly name: "PreconditionRequiredError";
|
|
1014
1071
|
readonly message: "Precondition required.";
|
|
1015
|
-
readonly uiMessage: "Required conditions are missing from the request.";
|
|
1016
1072
|
};
|
|
1017
1073
|
readonly 429: {
|
|
1018
1074
|
readonly code: "TOO_MANY_REQUESTS";
|
|
1019
1075
|
readonly name: "TooManyRequestsError";
|
|
1020
1076
|
readonly message: "Too many requests.";
|
|
1021
|
-
readonly uiMessage: "You have made too many requests. Please wait and try again.";
|
|
1022
1077
|
};
|
|
1023
1078
|
readonly 431: {
|
|
1024
1079
|
readonly code: "REQUEST_HEADER_FIELDS_TOO_LARGE";
|
|
1025
1080
|
readonly name: "RequestHeaderFieldsTooLargeError";
|
|
1026
1081
|
readonly message: "Request header fields too large.";
|
|
1027
|
-
readonly uiMessage: "The request headers are too large.";
|
|
1028
1082
|
};
|
|
1029
1083
|
readonly 451: {
|
|
1030
1084
|
readonly code: "UNAVAILABLE_FOR_LEGAL_REASONS";
|
|
1031
1085
|
readonly name: "UnavailableForLegalReasonsError";
|
|
1032
1086
|
readonly message: "Unavailable for legal reasons.";
|
|
1033
|
-
readonly uiMessage: "This content is unavailable for legal reasons.";
|
|
1034
1087
|
};
|
|
1035
1088
|
readonly 500: {
|
|
1036
1089
|
readonly code: "INTERNAL_SERVER_ERROR";
|
|
1037
1090
|
readonly name: "InternalServerError";
|
|
1038
1091
|
readonly message: "Internal server error.";
|
|
1039
|
-
readonly uiMessage: "An unexpected error occurred. Please try again later.";
|
|
1040
1092
|
};
|
|
1041
1093
|
readonly 501: {
|
|
1042
1094
|
readonly code: "NOT_IMPLEMENTED";
|
|
1043
1095
|
readonly name: "NotImplementedError";
|
|
1044
1096
|
readonly message: "Not implemented.";
|
|
1045
|
-
readonly uiMessage: "This feature is not yet available.";
|
|
1046
1097
|
};
|
|
1047
1098
|
readonly 502: {
|
|
1048
1099
|
readonly code: "BAD_GATEWAY";
|
|
1049
1100
|
readonly name: "BadGatewayError";
|
|
1050
1101
|
readonly message: "Bad gateway.";
|
|
1051
|
-
readonly uiMessage: "Unable to connect to the server. Please try again later.";
|
|
1052
1102
|
};
|
|
1053
1103
|
readonly 503: {
|
|
1054
1104
|
readonly code: "SERVICE_UNAVAILABLE";
|
|
1055
1105
|
readonly name: "ServiceUnavailableError";
|
|
1056
1106
|
readonly message: "Service unavailable.";
|
|
1057
|
-
readonly uiMessage: "The service is temporarily unavailable. Please try again later.";
|
|
1058
1107
|
};
|
|
1059
1108
|
readonly 504: {
|
|
1060
1109
|
readonly code: "GATEWAY_TIMEOUT";
|
|
1061
1110
|
readonly name: "GatewayTimeoutError";
|
|
1062
1111
|
readonly message: "Gateway timeout.";
|
|
1063
|
-
readonly uiMessage: "The server took too long to respond. Please try again.";
|
|
1064
1112
|
};
|
|
1065
1113
|
readonly 505: {
|
|
1066
1114
|
readonly code: "HTTP_VERSION_NOT_SUPPORTED";
|
|
1067
1115
|
readonly name: "HttpVersionNotSupportedError";
|
|
1068
1116
|
readonly message: "HTTP version not supported.";
|
|
1069
|
-
readonly uiMessage: "Your browser version is not supported.";
|
|
1070
1117
|
};
|
|
1071
1118
|
readonly 506: {
|
|
1072
1119
|
readonly code: "VARIANT_ALSO_NEGOTIATES";
|
|
1073
1120
|
readonly name: "VariantAlsoNegotiatesError";
|
|
1074
1121
|
readonly message: "Variant also negotiates.";
|
|
1075
|
-
readonly uiMessage: "The server has an internal configuration error.";
|
|
1076
1122
|
};
|
|
1077
1123
|
readonly 507: {
|
|
1078
1124
|
readonly code: "INSUFFICIENT_STORAGE";
|
|
1079
1125
|
readonly name: "InsufficientStorageError";
|
|
1080
1126
|
readonly message: "Insufficient storage.";
|
|
1081
|
-
readonly uiMessage: "The server has insufficient storage to complete the request.";
|
|
1082
1127
|
};
|
|
1083
1128
|
readonly 508: {
|
|
1084
1129
|
readonly code: "LOOP_DETECTED";
|
|
1085
1130
|
readonly name: "LoopDetectedError";
|
|
1086
1131
|
readonly message: "Loop detected.";
|
|
1087
|
-
readonly uiMessage: "The server detected an infinite loop.";
|
|
1088
1132
|
};
|
|
1089
1133
|
readonly 510: {
|
|
1090
1134
|
readonly code: "NOT_EXTENDED";
|
|
1091
1135
|
readonly name: "NotExtendedError";
|
|
1092
1136
|
readonly message: "Not extended.";
|
|
1093
|
-
readonly uiMessage: "Additional extensions are required.";
|
|
1094
1137
|
};
|
|
1095
1138
|
readonly 511: {
|
|
1096
1139
|
readonly code: "NETWORK_AUTHENTICATION_REQUIRED";
|
|
1097
1140
|
readonly name: "NetworkAuthenticationRequiredError";
|
|
1098
1141
|
readonly message: "Network authentication required.";
|
|
1099
|
-
readonly uiMessage: "Network authentication is required to access this resource.";
|
|
1100
1142
|
};
|
|
1101
1143
|
};
|
|
1144
|
+
/**
|
|
1145
|
+
* User-friendly messages for HTTP error presets.
|
|
1146
|
+
* Keyed by HTTP status code.
|
|
1147
|
+
*/
|
|
1148
|
+
declare const httpErrorUiMessages: Record<keyof typeof httpPresets, string>;
|
|
1102
1149
|
/**
|
|
1103
1150
|
* Valid HTTP status codes for HTTPErrorX.create()
|
|
1104
1151
|
* Derived from the presets object. Provides autocomplete for known codes
|
|
@@ -1172,235 +1219,196 @@ declare class HTTPErrorX extends ErrorX<HTTPErrorXMetadata> {
|
|
|
1172
1219
|
readonly code: "BAD_REQUEST";
|
|
1173
1220
|
readonly name: "BadRequestError";
|
|
1174
1221
|
readonly message: "Bad request.";
|
|
1175
|
-
readonly uiMessage: "The request could not be processed. Please check your input and try again.";
|
|
1176
1222
|
};
|
|
1177
1223
|
readonly 401: {
|
|
1178
1224
|
readonly code: "UNAUTHORIZED";
|
|
1179
1225
|
readonly name: "UnauthorizedError";
|
|
1180
1226
|
readonly message: "Unauthorized.";
|
|
1181
|
-
readonly uiMessage: "Authentication required. Please log in to continue.";
|
|
1182
1227
|
};
|
|
1183
1228
|
readonly 402: {
|
|
1184
1229
|
readonly code: "PAYMENT_REQUIRED";
|
|
1185
1230
|
readonly name: "PaymentRequiredError";
|
|
1186
1231
|
readonly message: "Payment required.";
|
|
1187
|
-
readonly uiMessage: "Payment is required to access this resource.";
|
|
1188
1232
|
};
|
|
1189
1233
|
readonly 403: {
|
|
1190
1234
|
readonly code: "FORBIDDEN";
|
|
1191
1235
|
readonly name: "ForbiddenError";
|
|
1192
1236
|
readonly message: "Forbidden.";
|
|
1193
|
-
readonly uiMessage: "You do not have permission to access this resource.";
|
|
1194
1237
|
};
|
|
1195
1238
|
readonly 404: {
|
|
1196
1239
|
readonly code: "NOT_FOUND";
|
|
1197
1240
|
readonly name: "NotFoundError";
|
|
1198
1241
|
readonly message: "Not found.";
|
|
1199
|
-
readonly uiMessage: "The requested resource could not be found.";
|
|
1200
1242
|
};
|
|
1201
1243
|
readonly 405: {
|
|
1202
1244
|
readonly code: "METHOD_NOT_ALLOWED";
|
|
1203
1245
|
readonly name: "MethodNotAllowedError";
|
|
1204
1246
|
readonly message: "Method not allowed.";
|
|
1205
|
-
readonly uiMessage: "This action is not allowed for the requested resource.";
|
|
1206
1247
|
};
|
|
1207
1248
|
readonly 406: {
|
|
1208
1249
|
readonly code: "NOT_ACCEPTABLE";
|
|
1209
1250
|
readonly name: "NotAcceptableError";
|
|
1210
1251
|
readonly message: "Not acceptable.";
|
|
1211
|
-
readonly uiMessage: "The requested format is not supported.";
|
|
1212
1252
|
};
|
|
1213
1253
|
readonly 407: {
|
|
1214
1254
|
readonly code: "PROXY_AUTHENTICATION_REQUIRED";
|
|
1215
1255
|
readonly name: "ProxyAuthenticationRequiredError";
|
|
1216
1256
|
readonly message: "Proxy authentication required.";
|
|
1217
|
-
readonly uiMessage: "Proxy authentication is required to access this resource.";
|
|
1218
1257
|
};
|
|
1219
1258
|
readonly 408: {
|
|
1220
1259
|
readonly code: "REQUEST_TIMEOUT";
|
|
1221
1260
|
readonly name: "RequestTimeoutError";
|
|
1222
1261
|
readonly message: "Request timeout.";
|
|
1223
|
-
readonly uiMessage: "The request took too long to complete. Please try again.";
|
|
1224
1262
|
};
|
|
1225
1263
|
readonly 409: {
|
|
1226
1264
|
readonly code: "CONFLICT";
|
|
1227
1265
|
readonly name: "ConflictError";
|
|
1228
1266
|
readonly message: "Conflict.";
|
|
1229
|
-
readonly uiMessage: "The request conflicts with the current state. Please refresh and try again.";
|
|
1230
1267
|
};
|
|
1231
1268
|
readonly 410: {
|
|
1232
1269
|
readonly code: "GONE";
|
|
1233
1270
|
readonly name: "GoneError";
|
|
1234
1271
|
readonly message: "Gone.";
|
|
1235
|
-
readonly uiMessage: "This resource is no longer available.";
|
|
1236
1272
|
};
|
|
1237
1273
|
readonly 411: {
|
|
1238
1274
|
readonly code: "LENGTH_REQUIRED";
|
|
1239
1275
|
readonly name: "LengthRequiredError";
|
|
1240
1276
|
readonly message: "Length required.";
|
|
1241
|
-
readonly uiMessage: "The request is missing required length information.";
|
|
1242
1277
|
};
|
|
1243
1278
|
readonly 412: {
|
|
1244
1279
|
readonly code: "PRECONDITION_FAILED";
|
|
1245
1280
|
readonly name: "PreconditionFailedError";
|
|
1246
1281
|
readonly message: "Precondition failed.";
|
|
1247
|
-
readonly uiMessage: "A required condition was not met. Please try again.";
|
|
1248
1282
|
};
|
|
1249
1283
|
readonly 413: {
|
|
1250
1284
|
readonly code: "PAYLOAD_TOO_LARGE";
|
|
1251
1285
|
readonly name: "PayloadTooLargeError";
|
|
1252
1286
|
readonly message: "Payload too large.";
|
|
1253
|
-
readonly uiMessage: "The request is too large. Please reduce the size and try again.";
|
|
1254
1287
|
};
|
|
1255
1288
|
readonly 414: {
|
|
1256
1289
|
readonly code: "URI_TOO_LONG";
|
|
1257
1290
|
readonly name: "UriTooLongError";
|
|
1258
1291
|
readonly message: "URI too long.";
|
|
1259
|
-
readonly uiMessage: "The request URL is too long.";
|
|
1260
1292
|
};
|
|
1261
1293
|
readonly 415: {
|
|
1262
1294
|
readonly code: "UNSUPPORTED_MEDIA_TYPE";
|
|
1263
1295
|
readonly name: "UnsupportedMediaTypeError";
|
|
1264
1296
|
readonly message: "Unsupported media type.";
|
|
1265
|
-
readonly uiMessage: "The file type is not supported.";
|
|
1266
1297
|
};
|
|
1267
1298
|
readonly 416: {
|
|
1268
1299
|
readonly code: "RANGE_NOT_SATISFIABLE";
|
|
1269
1300
|
readonly name: "RangeNotSatisfiableError";
|
|
1270
1301
|
readonly message: "Range not satisfiable.";
|
|
1271
|
-
readonly uiMessage: "The requested range cannot be satisfied.";
|
|
1272
1302
|
};
|
|
1273
1303
|
readonly 417: {
|
|
1274
1304
|
readonly code: "EXPECTATION_FAILED";
|
|
1275
1305
|
readonly name: "ExpectationFailedError";
|
|
1276
1306
|
readonly message: "Expectation failed.";
|
|
1277
|
-
readonly uiMessage: "The server cannot meet the requirements of the request.";
|
|
1278
1307
|
};
|
|
1279
1308
|
readonly 418: {
|
|
1280
1309
|
readonly code: "IM_A_TEAPOT";
|
|
1281
1310
|
readonly name: "ImATeapotError";
|
|
1282
1311
|
readonly message: "I'm a teapot.";
|
|
1283
|
-
readonly uiMessage: "I'm a teapot and cannot brew coffee.";
|
|
1284
1312
|
};
|
|
1285
1313
|
readonly 422: {
|
|
1286
1314
|
readonly code: "UNPROCESSABLE_ENTITY";
|
|
1287
1315
|
readonly name: "UnprocessableEntityError";
|
|
1288
1316
|
readonly message: "Unprocessable entity.";
|
|
1289
|
-
readonly uiMessage: "The request contains invalid data. Please check your input.";
|
|
1290
1317
|
};
|
|
1291
1318
|
readonly 423: {
|
|
1292
1319
|
readonly code: "LOCKED";
|
|
1293
1320
|
readonly name: "LockedError";
|
|
1294
1321
|
readonly message: "Locked.";
|
|
1295
|
-
readonly uiMessage: "This resource is locked and cannot be modified.";
|
|
1296
1322
|
};
|
|
1297
1323
|
readonly 424: {
|
|
1298
1324
|
readonly code: "FAILED_DEPENDENCY";
|
|
1299
1325
|
readonly name: "FailedDependencyError";
|
|
1300
1326
|
readonly message: "Failed dependency.";
|
|
1301
|
-
readonly uiMessage: "The request failed due to a dependency error.";
|
|
1302
1327
|
};
|
|
1303
1328
|
readonly 425: {
|
|
1304
1329
|
readonly code: "TOO_EARLY";
|
|
1305
1330
|
readonly name: "TooEarlyError";
|
|
1306
1331
|
readonly message: "Too early.";
|
|
1307
|
-
readonly uiMessage: "The request was sent too early. Please try again later.";
|
|
1308
1332
|
};
|
|
1309
1333
|
readonly 426: {
|
|
1310
1334
|
readonly code: "UPGRADE_REQUIRED";
|
|
1311
1335
|
readonly name: "UpgradeRequiredError";
|
|
1312
1336
|
readonly message: "Upgrade required.";
|
|
1313
|
-
readonly uiMessage: "Please upgrade to continue using this service.";
|
|
1314
1337
|
};
|
|
1315
1338
|
readonly 428: {
|
|
1316
1339
|
readonly code: "PRECONDITION_REQUIRED";
|
|
1317
1340
|
readonly name: "PreconditionRequiredError";
|
|
1318
1341
|
readonly message: "Precondition required.";
|
|
1319
|
-
readonly uiMessage: "Required conditions are missing from the request.";
|
|
1320
1342
|
};
|
|
1321
1343
|
readonly 429: {
|
|
1322
1344
|
readonly code: "TOO_MANY_REQUESTS";
|
|
1323
1345
|
readonly name: "TooManyRequestsError";
|
|
1324
1346
|
readonly message: "Too many requests.";
|
|
1325
|
-
readonly uiMessage: "You have made too many requests. Please wait and try again.";
|
|
1326
1347
|
};
|
|
1327
1348
|
readonly 431: {
|
|
1328
1349
|
readonly code: "REQUEST_HEADER_FIELDS_TOO_LARGE";
|
|
1329
1350
|
readonly name: "RequestHeaderFieldsTooLargeError";
|
|
1330
1351
|
readonly message: "Request header fields too large.";
|
|
1331
|
-
readonly uiMessage: "The request headers are too large.";
|
|
1332
1352
|
};
|
|
1333
1353
|
readonly 451: {
|
|
1334
1354
|
readonly code: "UNAVAILABLE_FOR_LEGAL_REASONS";
|
|
1335
1355
|
readonly name: "UnavailableForLegalReasonsError";
|
|
1336
1356
|
readonly message: "Unavailable for legal reasons.";
|
|
1337
|
-
readonly uiMessage: "This content is unavailable for legal reasons.";
|
|
1338
1357
|
};
|
|
1339
1358
|
readonly 500: {
|
|
1340
1359
|
readonly code: "INTERNAL_SERVER_ERROR";
|
|
1341
1360
|
readonly name: "InternalServerError";
|
|
1342
1361
|
readonly message: "Internal server error.";
|
|
1343
|
-
readonly uiMessage: "An unexpected error occurred. Please try again later.";
|
|
1344
1362
|
};
|
|
1345
1363
|
readonly 501: {
|
|
1346
1364
|
readonly code: "NOT_IMPLEMENTED";
|
|
1347
1365
|
readonly name: "NotImplementedError";
|
|
1348
1366
|
readonly message: "Not implemented.";
|
|
1349
|
-
readonly uiMessage: "This feature is not yet available.";
|
|
1350
1367
|
};
|
|
1351
1368
|
readonly 502: {
|
|
1352
1369
|
readonly code: "BAD_GATEWAY";
|
|
1353
1370
|
readonly name: "BadGatewayError";
|
|
1354
1371
|
readonly message: "Bad gateway.";
|
|
1355
|
-
readonly uiMessage: "Unable to connect to the server. Please try again later.";
|
|
1356
1372
|
};
|
|
1357
1373
|
readonly 503: {
|
|
1358
1374
|
readonly code: "SERVICE_UNAVAILABLE";
|
|
1359
1375
|
readonly name: "ServiceUnavailableError";
|
|
1360
1376
|
readonly message: "Service unavailable.";
|
|
1361
|
-
readonly uiMessage: "The service is temporarily unavailable. Please try again later.";
|
|
1362
1377
|
};
|
|
1363
1378
|
readonly 504: {
|
|
1364
1379
|
readonly code: "GATEWAY_TIMEOUT";
|
|
1365
1380
|
readonly name: "GatewayTimeoutError";
|
|
1366
1381
|
readonly message: "Gateway timeout.";
|
|
1367
|
-
readonly uiMessage: "The server took too long to respond. Please try again.";
|
|
1368
1382
|
};
|
|
1369
1383
|
readonly 505: {
|
|
1370
1384
|
readonly code: "HTTP_VERSION_NOT_SUPPORTED";
|
|
1371
1385
|
readonly name: "HttpVersionNotSupportedError";
|
|
1372
1386
|
readonly message: "HTTP version not supported.";
|
|
1373
|
-
readonly uiMessage: "Your browser version is not supported.";
|
|
1374
1387
|
};
|
|
1375
1388
|
readonly 506: {
|
|
1376
1389
|
readonly code: "VARIANT_ALSO_NEGOTIATES";
|
|
1377
1390
|
readonly name: "VariantAlsoNegotiatesError";
|
|
1378
1391
|
readonly message: "Variant also negotiates.";
|
|
1379
|
-
readonly uiMessage: "The server has an internal configuration error.";
|
|
1380
1392
|
};
|
|
1381
1393
|
readonly 507: {
|
|
1382
1394
|
readonly code: "INSUFFICIENT_STORAGE";
|
|
1383
1395
|
readonly name: "InsufficientStorageError";
|
|
1384
1396
|
readonly message: "Insufficient storage.";
|
|
1385
|
-
readonly uiMessage: "The server has insufficient storage to complete the request.";
|
|
1386
1397
|
};
|
|
1387
1398
|
readonly 508: {
|
|
1388
1399
|
readonly code: "LOOP_DETECTED";
|
|
1389
1400
|
readonly name: "LoopDetectedError";
|
|
1390
1401
|
readonly message: "Loop detected.";
|
|
1391
|
-
readonly uiMessage: "The server detected an infinite loop.";
|
|
1392
1402
|
};
|
|
1393
1403
|
readonly 510: {
|
|
1394
1404
|
readonly code: "NOT_EXTENDED";
|
|
1395
1405
|
readonly name: "NotExtendedError";
|
|
1396
1406
|
readonly message: "Not extended.";
|
|
1397
|
-
readonly uiMessage: "Additional extensions are required.";
|
|
1398
1407
|
};
|
|
1399
1408
|
readonly 511: {
|
|
1400
1409
|
readonly code: "NETWORK_AUTHENTICATION_REQUIRED";
|
|
1401
1410
|
readonly name: "NetworkAuthenticationRequiredError";
|
|
1402
1411
|
readonly message: "Network authentication required.";
|
|
1403
|
-
readonly uiMessage: "Network authentication is required to access this resource.";
|
|
1404
1412
|
};
|
|
1405
1413
|
};
|
|
1406
1414
|
/** Default to 500 Internal Server Error when no preset specified */
|
|
@@ -1465,6 +1473,10 @@ type ValidationErrorXMetadata = {
|
|
|
1465
1473
|
/** All Zod issues (for multi-error handling) */
|
|
1466
1474
|
issues?: ZodIssue[];
|
|
1467
1475
|
};
|
|
1476
|
+
/**
|
|
1477
|
+
* Default user-friendly message for validation errors.
|
|
1478
|
+
*/
|
|
1479
|
+
declare const validationErrorUiMessage = "The provided input is invalid. Please check your data.";
|
|
1468
1480
|
/**
|
|
1469
1481
|
* Validation Error class designed for Zod integration.
|
|
1470
1482
|
*
|
|
@@ -1502,7 +1514,6 @@ type ValidationErrorXMetadata = {
|
|
|
1502
1514
|
*
|
|
1503
1515
|
* // With overrides
|
|
1504
1516
|
* ValidationErrorX.fromZodError(zodError, {
|
|
1505
|
-
* uiMessage: 'Please check your input',
|
|
1506
1517
|
* httpStatus: 422,
|
|
1507
1518
|
* })
|
|
1508
1519
|
*
|
|
@@ -1520,7 +1531,7 @@ type ValidationErrorXMetadata = {
|
|
|
1520
1531
|
* if (err instanceof ValidationErrorX) {
|
|
1521
1532
|
* return res.status(err.httpStatus).json({
|
|
1522
1533
|
* error: err.code,
|
|
1523
|
-
* message: err.
|
|
1534
|
+
* message: err.message,
|
|
1524
1535
|
* field: err.metadata?.field,
|
|
1525
1536
|
* })
|
|
1526
1537
|
* }
|
|
@@ -1536,7 +1547,6 @@ declare class ValidationErrorX extends ErrorX<ValidationErrorXMetadata> {
|
|
|
1536
1547
|
name: string;
|
|
1537
1548
|
code: string;
|
|
1538
1549
|
message: string;
|
|
1539
|
-
uiMessage: string;
|
|
1540
1550
|
};
|
|
1541
1551
|
/**
|
|
1542
1552
|
* Transform that maps Zod issue codes to VALIDATION_ prefixed codes.
|
|
@@ -1566,9 +1576,9 @@ declare class ValidationErrorX extends ErrorX<ValidationErrorXMetadata> {
|
|
|
1566
1576
|
* }
|
|
1567
1577
|
* }
|
|
1568
1578
|
*
|
|
1569
|
-
* // With custom
|
|
1579
|
+
* // With custom message
|
|
1570
1580
|
* ValidationErrorX.fromZodError(zodError, {
|
|
1571
|
-
*
|
|
1581
|
+
* message: 'Please fix the form errors',
|
|
1572
1582
|
* })
|
|
1573
1583
|
*
|
|
1574
1584
|
* // Access all issues
|
|
@@ -1604,4 +1614,60 @@ declare class ValidationErrorX extends ErrorX<ValidationErrorXMetadata> {
|
|
|
1604
1614
|
static forField(field: string, message: string, options?: Partial<ErrorXOptions<ValidationErrorXMetadata>>): ValidationErrorX;
|
|
1605
1615
|
}
|
|
1606
1616
|
|
|
1607
|
-
|
|
1617
|
+
/**
|
|
1618
|
+
* Resolves ErrorX errors to enhanced presentation objects.
|
|
1619
|
+
* Supports i18n translations, documentation URLs, and custom properties.
|
|
1620
|
+
*
|
|
1621
|
+
* @example
|
|
1622
|
+
* ```typescript
|
|
1623
|
+
* const resolver = new ErrorXResolver({
|
|
1624
|
+
* i18n: { resolver: i18next.t },
|
|
1625
|
+
* docs: { baseUrl: 'https://docs.example.com' },
|
|
1626
|
+
* onResolveType: (error) => error.code.startsWith('API_') ? 'api' : 'general',
|
|
1627
|
+
* configs: {
|
|
1628
|
+
* api: { namespace: 'errors.api', docsPath: '/api' },
|
|
1629
|
+
* general: { namespace: 'errors' },
|
|
1630
|
+
* },
|
|
1631
|
+
* });
|
|
1632
|
+
*
|
|
1633
|
+
* const result = resolver.resolve(error, 'es');
|
|
1634
|
+
* ```
|
|
1635
|
+
*
|
|
1636
|
+
* @public
|
|
1637
|
+
*/
|
|
1638
|
+
declare class ErrorXResolver<TConfig extends ErrorXBaseConfig = ErrorXBaseConfig, TResult = ResolveContext<TConfig>> {
|
|
1639
|
+
private readonly options;
|
|
1640
|
+
private readonly defaultKeyTemplate;
|
|
1641
|
+
constructor(options: ErrorXResolverOptions<TConfig, TResult>);
|
|
1642
|
+
/**
|
|
1643
|
+
* Resolves an error to its enhanced representation.
|
|
1644
|
+
*
|
|
1645
|
+
* @param error - The ErrorX instance to resolve
|
|
1646
|
+
* @param _locale - Optional locale for i18n (passed to resolver function)
|
|
1647
|
+
* @returns The resolved result (ResolveContext or custom TResult)
|
|
1648
|
+
*/
|
|
1649
|
+
resolve(error: ErrorX, _locale?: string): TResult;
|
|
1650
|
+
/**
|
|
1651
|
+
* Merges config from defaults → type → preset
|
|
1652
|
+
*/
|
|
1653
|
+
private mergeConfig;
|
|
1654
|
+
/**
|
|
1655
|
+
* Builds the i18n key from template
|
|
1656
|
+
*/
|
|
1657
|
+
private buildI18nKey;
|
|
1658
|
+
/**
|
|
1659
|
+
* Resolves uiMessage following the priority order:
|
|
1660
|
+
* 1. presets[code].uiMessage (already merged into config if from preset)
|
|
1661
|
+
* 2. i18n resolver result (if configured)
|
|
1662
|
+
* 3. configs[errorType].uiMessage (fallback)
|
|
1663
|
+
* 4. defaults.uiMessage (fallback)
|
|
1664
|
+
* 5. undefined
|
|
1665
|
+
*/
|
|
1666
|
+
private resolveUiMessage;
|
|
1667
|
+
/**
|
|
1668
|
+
* Builds the full documentation URL
|
|
1669
|
+
*/
|
|
1670
|
+
private buildDocsUrl;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
export { type DBErrorXPresetKey as DBErrorPreset, DBErrorX, type DBErrorXMetadata, ErrorX, type ErrorXBaseConfig, type ErrorXConfig, type ErrorXMetadata, type ErrorXOptions, ErrorXResolver, type ErrorXResolverConfig, type ErrorXResolverDocsConfig, type ErrorXResolverI18nConfig, type ErrorXResolverOptions, type ErrorXResolverTypeConfig, type ErrorXSerialized, type ErrorXSnapshot, type ErrorXTransform, type ErrorXTransformContext, HTTPErrorX, type HTTPErrorXMetadata, type HTTPErrorXPresetKey as HTTPStatusCode, type ResolveContext, ValidationErrorX, type ValidationErrorXMetadata, type ZodIssue, dbErrorUiMessages, httpErrorUiMessages, validationErrorUiMessage };
|