@nice-code/error 0.0.20 → 0.1.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 +4 -0
- package/build/index.js +179 -39
- package/build/types/NiceError/NiceError.d.ts +14 -9
- package/build/types/NiceError/NiceError.types.d.ts +14 -9
- package/build/types/NiceError/NiceErrorHydrated.d.ts +10 -8
- package/build/types/NiceErrorDefined/NiceErrorDefined.d.ts +10 -10
- package/build/types/NiceErrorDefined/defineNiceError.d.ts +2 -2
- package/build/types/NiceErrorHandler/NiceErrorHandler.d.ts +23 -0
- package/build/types/NiceErrorHandler/NiceErrorHandler.types.d.ts +82 -0
- package/build/types/NiceErrorHandler/handleWith.d.ts +8 -0
- package/build/types/example/error_usage_example.d.ts +3 -3
- package/build/types/index.d.ts +3 -1
- package/build/types/internal/nice_core_errors.d.ts +7 -2
- package/build/types/test/helpers/nice_error_testing.static.d.ts +2 -2
- package/build/types/utils/castAndHydrate.d.ts +3 -3
- package/build/types/utils/matchFirst.d.ts +3 -3
- package/package.json +1 -1
- package/build/types/utils/handleWith.d.ts +0 -49
package/README.md
CHANGED
package/build/index.js
CHANGED
|
@@ -388,6 +388,7 @@ class NiceError extends Error {
|
|
|
388
388
|
ids;
|
|
389
389
|
wasntNice;
|
|
390
390
|
httpStatusCode;
|
|
391
|
+
timeCreated;
|
|
391
392
|
originError;
|
|
392
393
|
_packedState;
|
|
393
394
|
_errorDataMap;
|
|
@@ -401,6 +402,7 @@ class NiceError extends Error {
|
|
|
401
402
|
if (options.originError != null) {
|
|
402
403
|
this.originError = options.originError;
|
|
403
404
|
}
|
|
405
|
+
this.timeCreated = options.timeCreated ?? Date.now();
|
|
404
406
|
}
|
|
405
407
|
hasId(id) {
|
|
406
408
|
return id in this._errorDataMap;
|
|
@@ -478,7 +480,12 @@ class NiceError extends Error {
|
|
|
478
480
|
} else {
|
|
479
481
|
contextState = data.contextState;
|
|
480
482
|
}
|
|
481
|
-
errorData[id] = {
|
|
483
|
+
errorData[id] = {
|
|
484
|
+
contextState,
|
|
485
|
+
message: data.message,
|
|
486
|
+
httpStatusCode: data.httpStatusCode,
|
|
487
|
+
timeAdded: data.timeAdded
|
|
488
|
+
};
|
|
482
489
|
}
|
|
483
490
|
return {
|
|
484
491
|
name: "NiceError",
|
|
@@ -488,34 +495,49 @@ class NiceError extends Error {
|
|
|
488
495
|
wasntNice: this.wasntNice,
|
|
489
496
|
message: this.message,
|
|
490
497
|
httpStatusCode: this.httpStatusCode,
|
|
498
|
+
timeCreated: this.timeCreated,
|
|
491
499
|
...this.stack != null ? { stack: this.stack } : {},
|
|
492
500
|
originError
|
|
493
501
|
};
|
|
494
502
|
}
|
|
503
|
+
toJsonString() {
|
|
504
|
+
return JSON.stringify(this.toJsonObject());
|
|
505
|
+
}
|
|
506
|
+
toHttpResponse() {
|
|
507
|
+
return new Response(this.toJsonString(), {
|
|
508
|
+
status: this.httpStatusCode,
|
|
509
|
+
headers: { "Content-Type": "application/json" }
|
|
510
|
+
});
|
|
511
|
+
}
|
|
495
512
|
hydrate(definedNiceError) {
|
|
496
513
|
return definedNiceError.hydrate(this);
|
|
497
514
|
}
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
if (
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
515
|
+
handleWithSync(handlerInput, handlerOptions = {}) {
|
|
516
|
+
const handlersArray = Array.isArray(handlerInput) ? handlerInput : [handlerInput];
|
|
517
|
+
for (const handler of handlersArray) {
|
|
518
|
+
const result = handler.handleErrorWithPromiseInspection(this, handlerOptions);
|
|
519
|
+
if (result.matched) {
|
|
520
|
+
if (result.isPromise) {
|
|
521
|
+
console.warn(`[NiceError.handleWith] Handler ${result.target.identifier} returned a Promise but was called via \`handleWith\` (synchronous). ` + `The Promise will not be awaited. Use \`handleWithAsync\` for async handlers.`);
|
|
522
|
+
}
|
|
523
|
+
return result.isPromise ? undefined : result.handlerResponse;
|
|
524
|
+
}
|
|
506
525
|
}
|
|
507
|
-
|
|
526
|
+
if (handlerOptions.throwOnUnhandled === true)
|
|
527
|
+
throw this;
|
|
528
|
+
return;
|
|
508
529
|
}
|
|
509
|
-
async handleWithAsync(
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
return true;
|
|
530
|
+
async handleWithAsync(handlerInput, handlerOptions = {}) {
|
|
531
|
+
const handlersArray = Array.isArray(handlerInput) ? handlerInput : [handlerInput];
|
|
532
|
+
for (const handler of handlersArray) {
|
|
533
|
+
const result = handler.handleErrorWithPromiseInspection(this, handlerOptions);
|
|
534
|
+
if (result.matched) {
|
|
535
|
+
return result.isPromise ? await result.handlerPromise : result.handlerResponse;
|
|
536
|
+
}
|
|
517
537
|
}
|
|
518
|
-
|
|
538
|
+
if (handlerOptions.throwOnUnhandled === true)
|
|
539
|
+
throw this;
|
|
540
|
+
return;
|
|
519
541
|
}
|
|
520
542
|
get isPacked() {
|
|
521
543
|
return this._packedState != null;
|
|
@@ -595,7 +617,7 @@ class NiceErrorHydrated extends NiceError {
|
|
|
595
617
|
}
|
|
596
618
|
|
|
597
619
|
// src/NiceErrorDefined/NiceErrorDefined.ts
|
|
598
|
-
class
|
|
620
|
+
class NiceErrorDomain {
|
|
599
621
|
domain;
|
|
600
622
|
allDomains;
|
|
601
623
|
defaultHttpStatusCode;
|
|
@@ -620,7 +642,7 @@ class NiceErrorDefined {
|
|
|
620
642
|
}
|
|
621
643
|
}
|
|
622
644
|
createChildDomain(subErrorDef) {
|
|
623
|
-
const child = new
|
|
645
|
+
const child = new NiceErrorDomain({
|
|
624
646
|
domain: subErrorDef.domain,
|
|
625
647
|
allDomains: [subErrorDef.domain, ...this.allDomains],
|
|
626
648
|
schema: subErrorDef.schema,
|
|
@@ -676,9 +698,10 @@ class NiceErrorDefined {
|
|
|
676
698
|
if (errDef.domain !== this.domain) {
|
|
677
699
|
throw new Error(`[NiceErrorDefined.hydrate] Domain mismatch: this definition is "${this.domain}" ` + `but the error belongs to "${errDef.domain}". ` + `Call \`niceErrorDefined.is(error)\` before hydrating to ensure compatibility.`);
|
|
678
700
|
}
|
|
701
|
+
const finalError = error instanceof NiceError ? error : new NiceError(error);
|
|
679
702
|
const reconciledErrorData = {};
|
|
680
|
-
for (const id of
|
|
681
|
-
const existingData =
|
|
703
|
+
for (const id of finalError.getIds()) {
|
|
704
|
+
const existingData = finalError.getErrorDataForId(id);
|
|
682
705
|
if (existingData == null)
|
|
683
706
|
continue;
|
|
684
707
|
let contextState = existingData.contextState;
|
|
@@ -696,18 +719,20 @@ class NiceErrorDefined {
|
|
|
696
719
|
reconciledErrorData[id] = {
|
|
697
720
|
contextState,
|
|
698
721
|
message: existingData.message,
|
|
699
|
-
httpStatusCode: existingData.httpStatusCode
|
|
722
|
+
httpStatusCode: existingData.httpStatusCode,
|
|
723
|
+
timeAdded: existingData.timeAdded
|
|
700
724
|
};
|
|
701
725
|
}
|
|
702
726
|
return new NiceErrorHydrated({
|
|
703
727
|
def: this._buildDef(),
|
|
704
728
|
niceErrorDefined: this,
|
|
705
|
-
ids:
|
|
729
|
+
ids: finalError.ids,
|
|
706
730
|
errorData: reconciledErrorData,
|
|
707
|
-
message:
|
|
708
|
-
httpStatusCode:
|
|
709
|
-
wasntNice:
|
|
710
|
-
originError:
|
|
731
|
+
message: finalError.message,
|
|
732
|
+
httpStatusCode: finalError.httpStatusCode,
|
|
733
|
+
wasntNice: finalError.wasntNice,
|
|
734
|
+
originError: finalError.originError,
|
|
735
|
+
timeCreated: finalError.timeCreated
|
|
711
736
|
});
|
|
712
737
|
}
|
|
713
738
|
fromId(...args) {
|
|
@@ -798,13 +823,13 @@ class NiceErrorDefined {
|
|
|
798
823
|
} else {
|
|
799
824
|
contextState = { kind: "serde_unset" /* serde_unset */, value: context };
|
|
800
825
|
}
|
|
801
|
-
return { contextState, message, httpStatusCode };
|
|
826
|
+
return { contextState, message, httpStatusCode, timeAdded: Date.now() };
|
|
802
827
|
}
|
|
803
828
|
}
|
|
804
829
|
|
|
805
830
|
// src/NiceErrorDefined/defineNiceError.ts
|
|
806
831
|
var defineNiceError = (definition) => {
|
|
807
|
-
return new
|
|
832
|
+
return new NiceErrorDomain({
|
|
808
833
|
domain: definition.domain,
|
|
809
834
|
allDomains: [definition.domain],
|
|
810
835
|
schema: definition.schema,
|
|
@@ -880,6 +905,124 @@ var err_cast_not_nice = err_nice.createChildDomain({
|
|
|
880
905
|
})
|
|
881
906
|
}
|
|
882
907
|
});
|
|
908
|
+
var err_nice_handler = err_nice.createChildDomain({
|
|
909
|
+
domain: "err_nice_handler",
|
|
910
|
+
schema: {}
|
|
911
|
+
});
|
|
912
|
+
// src/NiceErrorHandler/NiceErrorHandler.types.ts
|
|
913
|
+
var EErrorHandlerTargetType;
|
|
914
|
+
((EErrorHandlerTargetType2) => {
|
|
915
|
+
EErrorHandlerTargetType2["ids"] = "ids";
|
|
916
|
+
EErrorHandlerTargetType2["domain"] = "domain";
|
|
917
|
+
EErrorHandlerTargetType2["default"] = "default";
|
|
918
|
+
})(EErrorHandlerTargetType ||= {});
|
|
919
|
+
|
|
920
|
+
// src/NiceErrorHandler/NiceErrorHandler.ts
|
|
921
|
+
class NiceErrorHandler {
|
|
922
|
+
handlerConfigs = [];
|
|
923
|
+
_defaultRequester;
|
|
924
|
+
handleErrorWithPromiseInspection(error, options) {
|
|
925
|
+
for (const handlerConfig of this.handlerConfigs) {
|
|
926
|
+
if (!handlerConfig._matcher(error))
|
|
927
|
+
continue;
|
|
928
|
+
const errorResult = handlerConfig._requester(error);
|
|
929
|
+
if (errorResult instanceof Promise) {
|
|
930
|
+
return {
|
|
931
|
+
isPromise: true,
|
|
932
|
+
matched: true,
|
|
933
|
+
target: handlerConfig.target,
|
|
934
|
+
handlerPromise: errorResult
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
return {
|
|
938
|
+
isPromise: false,
|
|
939
|
+
matched: true,
|
|
940
|
+
target: handlerConfig.target,
|
|
941
|
+
handlerResponse: errorResult
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
if (this._defaultRequester) {
|
|
945
|
+
const defaultResult = this._defaultRequester(error);
|
|
946
|
+
if (defaultResult instanceof Promise) {
|
|
947
|
+
return {
|
|
948
|
+
isPromise: true,
|
|
949
|
+
matched: true,
|
|
950
|
+
target: {
|
|
951
|
+
type: "default" /* default */,
|
|
952
|
+
identifier: "[matched:default]"
|
|
953
|
+
},
|
|
954
|
+
handlerPromise: defaultResult
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
return {
|
|
958
|
+
isPromise: false,
|
|
959
|
+
matched: true,
|
|
960
|
+
target: { type: "default" /* default */, identifier: "[matched:default]" },
|
|
961
|
+
handlerResponse: defaultResult
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
if (options?.throwOnUnhandled === true) {
|
|
965
|
+
throw error;
|
|
966
|
+
}
|
|
967
|
+
return {
|
|
968
|
+
matched: false,
|
|
969
|
+
attemptedTargets: this.handlerConfigs.map((config) => config.target)
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
forDomain(domain, handler) {
|
|
973
|
+
this.handlerConfigs.push({
|
|
974
|
+
target: {
|
|
975
|
+
type: "domain" /* domain */,
|
|
976
|
+
domain: domain.domain,
|
|
977
|
+
identifier: `[matched:domain:${domain.domain}]`
|
|
978
|
+
},
|
|
979
|
+
_matcher: (error) => domain.isExact(error),
|
|
980
|
+
_requester: (error) => handler(domain.hydrate(error))
|
|
981
|
+
});
|
|
982
|
+
return this;
|
|
983
|
+
}
|
|
984
|
+
forId(domain, id, handler) {
|
|
985
|
+
this.handlerConfigs.push({
|
|
986
|
+
target: {
|
|
987
|
+
type: "ids" /* ids */,
|
|
988
|
+
domain: domain.domain,
|
|
989
|
+
ids: [id],
|
|
990
|
+
identifier: `[matched:ids:${domain.domain}:${id}]`
|
|
991
|
+
},
|
|
992
|
+
_matcher: (error) => domain.isExact(error) && error.hasId(id),
|
|
993
|
+
_requester: (error) => handler(domain.hydrate(error))
|
|
994
|
+
});
|
|
995
|
+
return this;
|
|
996
|
+
}
|
|
997
|
+
forIds(domain, ids, handler) {
|
|
998
|
+
this.handlerConfigs.push({
|
|
999
|
+
target: {
|
|
1000
|
+
type: "ids" /* ids */,
|
|
1001
|
+
domain: domain.domain,
|
|
1002
|
+
ids,
|
|
1003
|
+
identifier: `[matched:ids:${domain.domain}:${ids.join(",")}]`
|
|
1004
|
+
},
|
|
1005
|
+
_matcher: (error) => domain.isExact(error) && ids.some((id) => error.hasId(id)),
|
|
1006
|
+
_requester: (error) => handler(domain.hydrate(error))
|
|
1007
|
+
});
|
|
1008
|
+
return this;
|
|
1009
|
+
}
|
|
1010
|
+
setDefaultHandler(handler) {
|
|
1011
|
+
this._defaultRequester = handler;
|
|
1012
|
+
return this;
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
// src/NiceErrorHandler/handleWith.ts
|
|
1017
|
+
function forDomain(domain, handler) {
|
|
1018
|
+
return new NiceErrorHandler().forDomain(domain, handler);
|
|
1019
|
+
}
|
|
1020
|
+
function forId(domain, id, handler) {
|
|
1021
|
+
return new NiceErrorHandler().forId(domain, id, handler);
|
|
1022
|
+
}
|
|
1023
|
+
function forIds(domain, ids, handler) {
|
|
1024
|
+
return new NiceErrorHandler().forIds(domain, ids, handler);
|
|
1025
|
+
}
|
|
883
1026
|
// src/utils/isNiceErrorObject.ts
|
|
884
1027
|
function isNiceErrorObject(obj) {
|
|
885
1028
|
if (typeof obj !== "object" || obj == null)
|
|
@@ -2704,13 +2847,6 @@ function castAndHydrate(value, niceErrorDefined) {
|
|
|
2704
2847
|
}
|
|
2705
2848
|
return casted;
|
|
2706
2849
|
}
|
|
2707
|
-
// src/utils/handleWith.ts
|
|
2708
|
-
function forDomain(domain, handler) {
|
|
2709
|
-
return { _domain: domain, _ids: undefined, _handler: handler };
|
|
2710
|
-
}
|
|
2711
|
-
function forIds(domain, ids, handler) {
|
|
2712
|
-
return { _domain: domain, _ids: ids, _handler: handler };
|
|
2713
|
-
}
|
|
2714
2850
|
// src/utils/matchFirst.ts
|
|
2715
2851
|
function matchFirst(error, handlers) {
|
|
2716
2852
|
for (const id of error.getIds()) {
|
|
@@ -2731,7 +2867,9 @@ export {
|
|
|
2731
2867
|
isRegularErrorJsonObject,
|
|
2732
2868
|
isNiceErrorObject,
|
|
2733
2869
|
forIds,
|
|
2870
|
+
forId,
|
|
2734
2871
|
forDomain,
|
|
2872
|
+
err_nice_handler,
|
|
2735
2873
|
err_nice,
|
|
2736
2874
|
err_cast_not_nice,
|
|
2737
2875
|
err,
|
|
@@ -2740,8 +2878,10 @@ export {
|
|
|
2740
2878
|
castNiceError,
|
|
2741
2879
|
castAndHydrate,
|
|
2742
2880
|
NiceErrorHydrated,
|
|
2743
|
-
|
|
2881
|
+
NiceErrorHandler,
|
|
2882
|
+
NiceErrorDomain,
|
|
2744
2883
|
NiceError,
|
|
2745
2884
|
EErrorPackType,
|
|
2885
|
+
EErrorHandlerTargetType,
|
|
2746
2886
|
EErrId_CastNotNice
|
|
2747
2887
|
};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { NiceErrorDomain } from "../NiceErrorDefined/NiceErrorDefined";
|
|
2
|
+
import type { NiceErrorHandler } from "../NiceErrorHandler/NiceErrorHandler";
|
|
3
|
+
import type { IHandleErrorOptions } from "../NiceErrorHandler/NiceErrorHandler.types";
|
|
3
4
|
import { EErrorPackType } from "../utils/packError/packError.enums";
|
|
4
|
-
import { type
|
|
5
|
+
import { type INiceErrorDomainProps, type INiceErrorJsonObject, type IRegularErrorJsonObject, type TDomainNiceErrorId, type TErrorDataForIdMap, type TErrorReconciledData, type TExtractContextType, type TNiceErrorSchema, type TUnknownNiceErrorDef } from "./NiceError.types";
|
|
5
6
|
import type { NiceErrorHydrated } from "./NiceErrorHydrated";
|
|
6
7
|
type ContextOf<S extends TNiceErrorSchema, K extends keyof S> = TExtractContextType<S[K]>;
|
|
7
8
|
/** Full-featured construction from NiceErrorDefined.fromId / fromContext. */
|
|
8
|
-
export interface INiceErrorOptions<ERR_DEF extends
|
|
9
|
+
export interface INiceErrorOptions<ERR_DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> {
|
|
9
10
|
def: Omit<ERR_DEF, "schema">;
|
|
10
11
|
/** Primary id is first entry in ids. */
|
|
11
12
|
ids: ID[];
|
|
@@ -15,8 +16,9 @@ export interface INiceErrorOptions<ERR_DEF extends INiceErrorDefinedProps, ID ex
|
|
|
15
16
|
wasntNice?: boolean;
|
|
16
17
|
httpStatusCode?: number;
|
|
17
18
|
originError?: IRegularErrorJsonObject | undefined;
|
|
19
|
+
timeCreated?: number;
|
|
18
20
|
}
|
|
19
|
-
export declare class NiceError<ERR_DEF extends
|
|
21
|
+
export declare class NiceError<ERR_DEF extends INiceErrorDomainProps = TUnknownNiceErrorDef,
|
|
20
22
|
/**
|
|
21
23
|
* Union of active error-id keys.
|
|
22
24
|
* - After `fromId(id)`: exactly one key.
|
|
@@ -24,13 +26,14 @@ export declare class NiceError<ERR_DEF extends INiceErrorDefinedProps = TUnknown
|
|
|
24
26
|
* - After `hasOneOfIds([a,b])`: narrows to that subset.
|
|
25
27
|
* - Default (bare construction / castNiceError): `TUnknownNiceErrorId`.
|
|
26
28
|
*/
|
|
27
|
-
ACTIVE_IDS extends
|
|
29
|
+
ACTIVE_IDS extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> extends Error {
|
|
28
30
|
readonly name: "NiceError";
|
|
29
31
|
readonly def: Omit<ERR_DEF, "schema">;
|
|
30
32
|
/** Primary id is first entry in ids. */
|
|
31
33
|
readonly ids: ACTIVE_IDS[];
|
|
32
34
|
readonly wasntNice: boolean;
|
|
33
35
|
readonly httpStatusCode: number;
|
|
36
|
+
readonly timeCreated: number;
|
|
34
37
|
originError?: IRegularErrorJsonObject;
|
|
35
38
|
_packedState?: {
|
|
36
39
|
packedAs: EErrorPackType.cause_pack;
|
|
@@ -88,7 +91,9 @@ ACTIVE_IDS extends keyof ERR_DEF["schema"] & string = keyof ERR_DEF["schema"] &
|
|
|
88
91
|
*/
|
|
89
92
|
matches(other: NiceError<any, any>): boolean;
|
|
90
93
|
toJsonObject(): INiceErrorJsonObject<ERR_DEF>;
|
|
91
|
-
|
|
94
|
+
toJsonString(): string;
|
|
95
|
+
toHttpResponse(): Response;
|
|
96
|
+
hydrate(definedNiceError: NiceErrorDomain<ERR_DEF>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS>;
|
|
92
97
|
/**
|
|
93
98
|
* Iterates `cases` in order, finds the first whose domain matches this error
|
|
94
99
|
* (via `is()`), optionally further filters by active ids, hydrates the error,
|
|
@@ -117,7 +122,7 @@ ACTIVE_IDS extends keyof ERR_DEF["schema"] & string = keyof ERR_DEF["schema"] &
|
|
|
117
122
|
* if (!handled) next(error);
|
|
118
123
|
* ```
|
|
119
124
|
*/
|
|
120
|
-
|
|
125
|
+
handleWithSync<RD, R>(handlerInput: NiceErrorHandler<RD, R> | ReadonlyArray<NiceErrorHandler<RD, R>>, handlerOptions?: IHandleErrorOptions): R | RD | undefined;
|
|
121
126
|
/**
|
|
122
127
|
* Same matching logic as `handleWith`, but `await`s the handler's returned
|
|
123
128
|
* Promise before resolving. Use this when your handlers perform async work
|
|
@@ -133,7 +138,7 @@ ACTIVE_IDS extends keyof ERR_DEF["schema"] & string = keyof ERR_DEF["schema"] &
|
|
|
133
138
|
* ]);
|
|
134
139
|
* ```
|
|
135
140
|
*/
|
|
136
|
-
handleWithAsync(
|
|
141
|
+
handleWithAsync<RD, R>(handlerInput: NiceErrorHandler<RD, R> | ReadonlyArray<NiceErrorHandler<RD, R>>, handlerOptions?: IHandleErrorOptions): Promise<R | RD | undefined>;
|
|
137
142
|
get isPacked(): boolean;
|
|
138
143
|
pack(packType?: EErrorPackType): this;
|
|
139
144
|
unpack(): this;
|
|
@@ -111,6 +111,7 @@ export type TErrorReconciledData<SCHEMA extends TNiceErrorSchema, K extends keyo
|
|
|
111
111
|
contextState: TContextState<TExtractContextType<SCHEMA[K]>>;
|
|
112
112
|
message: string;
|
|
113
113
|
httpStatusCode: number;
|
|
114
|
+
timeAdded: number;
|
|
114
115
|
};
|
|
115
116
|
/**
|
|
116
117
|
* Wire-safe reconciled data — uses `TSerializedContextState` (no `"hydrated"`).
|
|
@@ -118,24 +119,25 @@ export type TErrorReconciledData<SCHEMA extends TNiceErrorSchema, K extends keyo
|
|
|
118
119
|
* over the wire. `"hydrated"` is excluded so that the serialization state can
|
|
119
120
|
* never be trusted after a JSON round-trip.
|
|
120
121
|
*/
|
|
121
|
-
export type TSerializedErrorReconciledData<SCHEMA extends TNiceErrorSchema, K extends
|
|
122
|
+
export type TSerializedErrorReconciledData<SCHEMA extends TNiceErrorSchema, K extends TSchemaNiceErrorId<SCHEMA>> = {
|
|
122
123
|
contextState: TSerializedContextState<TExtractContextType<SCHEMA[K]>>;
|
|
123
124
|
message: string;
|
|
124
125
|
httpStatusCode: number;
|
|
126
|
+
timeAdded: number;
|
|
125
127
|
};
|
|
126
|
-
export type TErrorDataForIdMap<SCHEMA extends TNiceErrorSchema> = {
|
|
127
|
-
[
|
|
128
|
+
export type TErrorDataForIdMap<SCHEMA extends TNiceErrorSchema, K extends TSchemaNiceErrorId<SCHEMA> = TSchemaNiceErrorId<SCHEMA>> = {
|
|
129
|
+
[key in K]?: TErrorReconciledData<SCHEMA, K>;
|
|
128
130
|
};
|
|
129
131
|
/** Wire-safe version of `TErrorDataForIdMap`. Used in `INiceErrorJsonObject`. */
|
|
130
132
|
export type TSerializedErrorDataMap<SCHEMA extends TNiceErrorSchema> = {
|
|
131
|
-
[K in
|
|
133
|
+
[K in TSchemaNiceErrorId<SCHEMA>]?: TSerializedErrorReconciledData<SCHEMA, K>;
|
|
132
134
|
};
|
|
133
135
|
/**
|
|
134
136
|
* The Partial record that `fromContext` accepts: callers supply one or more
|
|
135
137
|
* { [errorId]: contextValue } entries and NiceError stores them all.
|
|
136
138
|
*/
|
|
137
139
|
export type TFromContextInput<SCHEMA extends TNiceErrorSchema> = {
|
|
138
|
-
[K in
|
|
140
|
+
[K in TSchemaNiceErrorId<SCHEMA>]?: TExtractContextType<SCHEMA[K]> | undefined;
|
|
139
141
|
};
|
|
140
142
|
/**
|
|
141
143
|
* Resolves the args tuple for `fromId` / `addId`:
|
|
@@ -144,7 +146,7 @@ export type TFromContextInput<SCHEMA extends TNiceErrorSchema> = {
|
|
|
144
146
|
* - Context defined, `required: true` → `[id, context]`
|
|
145
147
|
* - Context defined, `required` absent/false → `[id] | [id, context]`
|
|
146
148
|
*/
|
|
147
|
-
export type FromIdArgs<ERR_DEF extends
|
|
149
|
+
export type FromIdArgs<ERR_DEF extends INiceErrorDomainProps, K extends TDomainNiceErrorId<ERR_DEF>> = [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] extends [undefined] ? [id: K] : [undefined] extends [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] ? [id: K] | [id: K, context: NonNullable<ExtractFromIdContextArg<ERR_DEF["schema"][K]>>] : [id: K, context: ExtractFromIdContextArg<ERR_DEF["schema"][K]>];
|
|
148
150
|
export interface IPackErrorAs_Base {
|
|
149
151
|
packAs: EErrorPackType;
|
|
150
152
|
}
|
|
@@ -158,7 +160,7 @@ export interface IDefineNewNiceErrorDomainOptions<ERR_DOMAIN extends string = st
|
|
|
158
160
|
domain: ERR_DOMAIN;
|
|
159
161
|
schema: SCHEMA;
|
|
160
162
|
}
|
|
161
|
-
export interface
|
|
163
|
+
export interface INiceErrorDomainProps<ERR_DOMAINS extends string[] = string[], SCHEMA extends TNiceErrorSchema = TNiceErrorSchema> {
|
|
162
164
|
packAs?: () => EErrorPackType | void;
|
|
163
165
|
defaultHttpStatusCode?: number;
|
|
164
166
|
defaultMessage?: string;
|
|
@@ -166,7 +168,7 @@ export interface INiceErrorDefinedProps<ERR_DOMAINS extends string[] = string[],
|
|
|
166
168
|
allDomains: ERR_DOMAINS;
|
|
167
169
|
schema: SCHEMA;
|
|
168
170
|
}
|
|
169
|
-
export interface INiceErrorJsonObject<ERR_DEF extends
|
|
171
|
+
export interface INiceErrorJsonObject<ERR_DEF extends INiceErrorDomainProps = INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> {
|
|
170
172
|
name: "NiceError";
|
|
171
173
|
def: Omit<ERR_DEF, "schema">;
|
|
172
174
|
ids: ID[];
|
|
@@ -179,7 +181,10 @@ export interface INiceErrorJsonObject<ERR_DEF extends INiceErrorDefinedProps = I
|
|
|
179
181
|
stack?: string;
|
|
180
182
|
cause?: unknown;
|
|
181
183
|
originError?: IRegularErrorJsonObject | undefined;
|
|
184
|
+
timeCreated: number;
|
|
182
185
|
}
|
|
186
|
+
export type TSchemaNiceErrorId<SCHEMA extends TNiceErrorSchema> = keyof SCHEMA & string;
|
|
187
|
+
export type TDomainNiceErrorId<ERR_DEF extends INiceErrorDomainProps> = TSchemaNiceErrorId<ERR_DEF["schema"]>;
|
|
183
188
|
/**
|
|
184
189
|
* The widest ERR_DEF used when creating a NiceError without a definition
|
|
185
190
|
* (bare construction, castNiceError, etc.).
|
|
@@ -189,7 +194,7 @@ export interface INiceErrorJsonObject<ERR_DEF extends INiceErrorDefinedProps = I
|
|
|
189
194
|
* correctly — `string & "specific_domain"` narrows to `"specific_domain"`
|
|
190
195
|
* instead of collapsing the intersection to `never`.
|
|
191
196
|
*/
|
|
192
|
-
export type TUnknownNiceErrorDef =
|
|
197
|
+
export type TUnknownNiceErrorDef = INiceErrorDomainProps;
|
|
193
198
|
/**
|
|
194
199
|
* Wide id type for bare / cast NiceErrors that have no schema.
|
|
195
200
|
* Using `string` (rather than a literal `"unknown"`) ensures that
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NiceErrorDomain } from "../NiceErrorDefined/NiceErrorDefined";
|
|
2
2
|
import { type INiceErrorOptions, NiceError } from "./NiceError";
|
|
3
|
-
import type { ExtractFromIdContextArg,
|
|
3
|
+
import type { ExtractFromIdContextArg, INiceErrorDomainProps, TDomainNiceErrorId, TFromContextInput, TUnknownNiceErrorDef } from "./NiceError.types";
|
|
4
4
|
/**
|
|
5
5
|
* Resolves the args tuple for `addId` — mirrors `FromIdArgs` exactly so that
|
|
6
6
|
* optional vs required context is consistent across both `fromId` and `addId`.
|
|
@@ -9,13 +9,15 @@ import type { ExtractFromIdContextArg, INiceErrorDefinedProps, TFromContextInput
|
|
|
9
9
|
* - Context defined, `required: true` → `[id, context]`
|
|
10
10
|
* - Context defined, `required` absent/false → `[id] | [id, context]`
|
|
11
11
|
*/
|
|
12
|
-
type AddIdArgs<ERR_DEF extends
|
|
12
|
+
type AddIdArgs<ERR_DEF extends INiceErrorDomainProps, K extends TDomainNiceErrorId<ERR_DEF>> = [
|
|
13
|
+
ExtractFromIdContextArg<ERR_DEF["schema"][K]>
|
|
14
|
+
] extends [undefined] ? [id: K] : [undefined] extends [ExtractFromIdContextArg<ERR_DEF["schema"][K]>] ? [id: K] | [id: K, context: NonNullable<ExtractFromIdContextArg<ERR_DEF["schema"][K]>>] : [id: K, context: ExtractFromIdContextArg<ERR_DEF["schema"][K]>];
|
|
13
15
|
/** Full-featured construction from NiceErrorDefined.fromId / fromContext. */
|
|
14
|
-
export interface INiceErrorHydratedOptions<ERR_DEF extends
|
|
16
|
+
export interface INiceErrorHydratedOptions<ERR_DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DEF>> extends INiceErrorOptions<ERR_DEF, ID> {
|
|
15
17
|
def: ERR_DEF;
|
|
16
|
-
niceErrorDefined:
|
|
18
|
+
niceErrorDefined: NiceErrorDomain<ERR_DEF>;
|
|
17
19
|
}
|
|
18
|
-
export declare class NiceErrorHydrated<ERR_DEF extends
|
|
20
|
+
export declare class NiceErrorHydrated<ERR_DEF extends INiceErrorDomainProps = TUnknownNiceErrorDef,
|
|
19
21
|
/**
|
|
20
22
|
* Union of active error-id keys.
|
|
21
23
|
* - After `fromId(id)`: exactly one key.
|
|
@@ -23,7 +25,7 @@ export declare class NiceErrorHydrated<ERR_DEF extends INiceErrorDefinedProps =
|
|
|
23
25
|
* - After `hasOneOfIds([a,b])`: narrows to that subset.
|
|
24
26
|
* - Default (bare construction / castNiceError): `TUnknownNiceErrorId`.
|
|
25
27
|
*/
|
|
26
|
-
ACTIVE_IDS extends
|
|
28
|
+
ACTIVE_IDS extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>> extends NiceError<ERR_DEF, ACTIVE_IDS> {
|
|
27
29
|
readonly def: ERR_DEF;
|
|
28
30
|
private readonly niceErrorDefined;
|
|
29
31
|
constructor(options: INiceErrorHydratedOptions<ERR_DEF, ACTIVE_IDS>);
|
|
@@ -44,6 +46,6 @@ ACTIVE_IDS extends keyof ERR_DEF["schema"] & string = keyof ERR_DEF["schema"] &
|
|
|
44
46
|
* if the schema requires one). Equivalent to `addContext({ [id]: context })`
|
|
45
47
|
* but mirrors the `fromId` ergonomics for single-id additions.
|
|
46
48
|
*/
|
|
47
|
-
addId<K extends
|
|
49
|
+
addId<K extends TDomainNiceErrorId<ERR_DEF>>(...args: AddIdArgs<ERR_DEF, K>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS | K>;
|
|
48
50
|
}
|
|
49
51
|
export {};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { NiceError } from "../NiceError/NiceError";
|
|
2
|
-
import { type FromIdArgs, type IDefineNewNiceErrorDomainOptions, type
|
|
2
|
+
import { type FromIdArgs, type IDefineNewNiceErrorDomainOptions, type INiceErrorDomainProps, type INiceErrorJsonObject, type TDomainNiceErrorId, type TErrorReconciledData, type TFromContextInput } from "../NiceError/NiceError.types";
|
|
3
3
|
import { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
|
|
4
4
|
import { type EErrorPackType } from "../utils/packError/packError.enums";
|
|
5
|
-
type ChildDef<PARENT_DEF extends
|
|
5
|
+
type ChildDef<PARENT_DEF extends INiceErrorDomainProps, SUB extends IDefineNewNiceErrorDomainOptions> = {
|
|
6
6
|
domain: SUB["domain"];
|
|
7
7
|
allDomains: [SUB["domain"], ...PARENT_DEF["allDomains"]];
|
|
8
8
|
schema: SUB["schema"];
|
|
@@ -25,7 +25,7 @@ type KeysOfContextInput<INPUT> = keyof INPUT & string;
|
|
|
25
25
|
* // → NiceError<{ domain: "err_user_auth"; ... }, keyof schema>
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
export type InferNiceError<T extends
|
|
28
|
+
export type InferNiceError<T extends NiceErrorDomain<any>> = T extends NiceErrorDomain<infer ERR_DEF> ? NiceError<ERR_DEF, keyof ERR_DEF["schema"] & string> : never;
|
|
29
29
|
/**
|
|
30
30
|
* Infers the strongly-typed `NiceErrorHydrated` class type from a `NiceErrorDefined` instance.
|
|
31
31
|
*
|
|
@@ -39,8 +39,8 @@ export type InferNiceError<T extends NiceErrorDefined<any>> = T extends NiceErro
|
|
|
39
39
|
* // → NiceErrorHydrated<{ domain: "err_user_auth"; ... }, keyof schema>
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
|
-
export type InferNiceErrorHydrated<T extends
|
|
43
|
-
export declare class
|
|
42
|
+
export type InferNiceErrorHydrated<T extends NiceErrorDomain<any>> = T extends NiceErrorDomain<infer ERR_DEF> ? NiceErrorHydrated<ERR_DEF, keyof ERR_DEF["schema"] & string> : never;
|
|
43
|
+
export declare class NiceErrorDomain<ERR_DEF extends INiceErrorDomainProps = INiceErrorDomainProps> {
|
|
44
44
|
readonly domain: ERR_DEF["domain"];
|
|
45
45
|
readonly allDomains: ERR_DEF["allDomains"];
|
|
46
46
|
readonly defaultHttpStatusCode?: number;
|
|
@@ -60,9 +60,9 @@ export declare class NiceErrorDefined<ERR_DEF extends INiceErrorDefinedProps = I
|
|
|
60
60
|
*/
|
|
61
61
|
createChildDomain<SUB extends IDefineNewNiceErrorDomainOptions>(subErrorDef: SUB & {
|
|
62
62
|
[K in Exclude<keyof SUB, keyof IDefineNewNiceErrorDomainOptions>]: never;
|
|
63
|
-
}):
|
|
64
|
-
protected addParentNiceErrorDefined<PARENT_DEF extends
|
|
65
|
-
protected addChildNiceErrorDefined<CHILD_DEF extends
|
|
63
|
+
}): NiceErrorDomain<ChildDef<ERR_DEF, SUB>>;
|
|
64
|
+
protected addParentNiceErrorDefined<PARENT_DEF extends INiceErrorDomainProps>(parentError: NiceErrorDomain<PARENT_DEF>): void;
|
|
65
|
+
protected addChildNiceErrorDefined<CHILD_DEF extends INiceErrorDomainProps>(child: NiceErrorDomain<CHILD_DEF>): void;
|
|
66
66
|
packAs(pack: EErrorPackType): this;
|
|
67
67
|
private createError;
|
|
68
68
|
/**
|
|
@@ -88,7 +88,7 @@ export declare class NiceErrorDefined<ERR_DEF extends INiceErrorDefinedProps = I
|
|
|
88
88
|
* }
|
|
89
89
|
* ```
|
|
90
90
|
*/
|
|
91
|
-
hydrate<ACTIVE_IDS extends
|
|
91
|
+
hydrate<ACTIVE_IDS extends TDomainNiceErrorId<ERR_DEF> = TDomainNiceErrorId<ERR_DEF>>(error: NiceError<ERR_DEF, ACTIVE_IDS> | INiceErrorJsonObject<ERR_DEF, ACTIVE_IDS>): NiceErrorHydrated<ERR_DEF, ACTIVE_IDS>;
|
|
92
92
|
/**
|
|
93
93
|
* Creates a `NiceErrorHydrated` for a single error id.
|
|
94
94
|
*
|
|
@@ -126,7 +126,7 @@ export declare class NiceErrorDefined<ERR_DEF extends INiceErrorDefinedProps = I
|
|
|
126
126
|
* Accepts either a `NiceErrorDefined` (domain definition) or a `NiceError`
|
|
127
127
|
* instance (extracts the domain from its `def`).
|
|
128
128
|
*/
|
|
129
|
-
isParentOf(target:
|
|
129
|
+
isParentOf(target: NiceErrorDomain<any> | NiceError<any, any>): boolean;
|
|
130
130
|
private _buildDef;
|
|
131
131
|
private _resolveMessage;
|
|
132
132
|
private _resolveHttpStatusCode;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IDefineNewNiceErrorDomainOptions, TNiceErrorSchema } from "../NiceError/NiceError.types";
|
|
2
|
-
import {
|
|
3
|
-
export declare const defineNiceError: <ERR_DOMAIN extends string, SCHEMA extends TNiceErrorSchema>(definition: IDefineNewNiceErrorDomainOptions<ERR_DOMAIN, SCHEMA>) =>
|
|
2
|
+
import { NiceErrorDomain } from "./NiceErrorDefined";
|
|
3
|
+
export declare const defineNiceError: <ERR_DOMAIN extends string, SCHEMA extends TNiceErrorSchema>(definition: IDefineNewNiceErrorDomainOptions<ERR_DOMAIN, SCHEMA>) => NiceErrorDomain<{
|
|
4
4
|
domain: ERR_DOMAIN;
|
|
5
5
|
allDomains: [ERR_DOMAIN];
|
|
6
6
|
schema: SCHEMA;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { NiceError } from "../NiceError/NiceError";
|
|
2
|
+
import type { INiceErrorDomainProps, TDomainNiceErrorId } from "../NiceError/NiceError.types";
|
|
3
|
+
import type { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
|
|
4
|
+
import type { NiceErrorDomain } from "../NiceErrorDefined/NiceErrorDefined";
|
|
5
|
+
import { type IHandleErrorOptions, type MaybePromise, type THandleErrorWithPromiseInspection } from "./NiceErrorHandler.types";
|
|
6
|
+
export declare class NiceErrorHandler<RES_DEF = never, RES = never> {
|
|
7
|
+
private handlerConfigs;
|
|
8
|
+
private _defaultRequester?;
|
|
9
|
+
handleErrorWithPromiseInspection(error: NiceError<any, any>, options?: IHandleErrorOptions): THandleErrorWithPromiseInspection<RES | RES_DEF>;
|
|
10
|
+
/**
|
|
11
|
+
* Register a handler that fires for **any** error whose domain matches `domain`.
|
|
12
|
+
* The handler receives a fully hydrated error — `getContext`, `addId`, and `addContext`
|
|
13
|
+
* are all available. First matching case wins.
|
|
14
|
+
*/
|
|
15
|
+
forDomain<DEF extends INiceErrorDomainProps, H_RES = void>(domain: NiceErrorDomain<DEF>, handler: (error: NiceErrorHydrated<DEF, TDomainNiceErrorId<DEF>>) => MaybePromise<H_RES>): NiceErrorHandler<RES_DEF, RES | H_RES>;
|
|
16
|
+
forId<DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<DEF>, H_RES = void>(domain: NiceErrorDomain<DEF>, id: ID, handler: (error: NiceErrorHydrated<DEF, ID>) => MaybePromise<H_RES>): NiceErrorHandler<RES_DEF, RES | H_RES>;
|
|
17
|
+
forIds<DEF extends INiceErrorDomainProps, IDS extends TDomainNiceErrorId<DEF>[], H_RES = void>(domain: NiceErrorDomain<DEF>, ids: IDS, handler: (error: NiceErrorHydrated<DEF, IDS[number]>) => MaybePromise<H_RES>): NiceErrorHandler<RES_DEF, RES | H_RES>;
|
|
18
|
+
/**
|
|
19
|
+
* Register a fallback handler that fires when no other case matches.
|
|
20
|
+
* Only one default handler can be registered — calling this twice replaces the previous one.
|
|
21
|
+
*/
|
|
22
|
+
setDefaultHandler<H_RES>(handler: (error: NiceError<any, any>) => MaybePromise<H_RES>): NiceErrorHandler<H_RES, RES>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { NiceError } from "../NiceError/NiceError";
|
|
2
|
+
import type { INiceErrorDomainProps, TDomainNiceErrorId } from "../NiceError/NiceError.types";
|
|
3
|
+
import type { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
|
|
4
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
5
|
+
/**
|
|
6
|
+
* Broad handler signature used internally for storage and dispatch.
|
|
7
|
+
*/
|
|
8
|
+
export type TBroadErrorHandler<E extends NiceError = NiceError, RES = unknown> = (action: E) => MaybePromise<RES>;
|
|
9
|
+
/**
|
|
10
|
+
* Handler registered via forDomain.
|
|
11
|
+
*
|
|
12
|
+
* `act.input` is typed as the union of input types for every action in `ACT_DOM`,
|
|
13
|
+
* and `act.coreAction` carries the matching schema — the same narrowing you get
|
|
14
|
+
* from `forActionIds` over all action IDs in the domain.
|
|
15
|
+
*/
|
|
16
|
+
export type TErrorHandlerForDomain<ERR_DOM extends INiceErrorDomainProps> = (error: NiceErrorHydrated<ERR_DOM>) => MaybePromise<unknown>;
|
|
17
|
+
/**
|
|
18
|
+
* Handler registered via forActionId — receives a specific action ID, with
|
|
19
|
+
* the primed action's input narrowed to that ID's schema.
|
|
20
|
+
*/
|
|
21
|
+
export type TErrorIdHandlerForDomain<ERR_DOM extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<ERR_DOM>> = (error: NiceErrorHydrated<ERR_DOM, ID>) => MaybePromise<unknown>;
|
|
22
|
+
export declare enum EErrorHandlerTargetType {
|
|
23
|
+
ids = "ids",
|
|
24
|
+
domain = "domain",
|
|
25
|
+
default = "default"
|
|
26
|
+
}
|
|
27
|
+
export type TErrorHandlerTarget = ({
|
|
28
|
+
type: EErrorHandlerTargetType.ids;
|
|
29
|
+
domain: string;
|
|
30
|
+
ids: string[];
|
|
31
|
+
} | {
|
|
32
|
+
type: EErrorHandlerTargetType.domain;
|
|
33
|
+
domain: string;
|
|
34
|
+
} | {
|
|
35
|
+
type: EErrorHandlerTargetType.default;
|
|
36
|
+
}) & {
|
|
37
|
+
identifier: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* A single case in a `handleWith` / `handleWithAsync` call.
|
|
41
|
+
*
|
|
42
|
+
* Construct via `forDomain` or `forIds` — do not build this object directly.
|
|
43
|
+
*/
|
|
44
|
+
export interface IErrorHandlerConfig<ERR extends NiceError<any, any> = NiceError<any, any>, RES = unknown> {
|
|
45
|
+
readonly _matcher: (action: ERR) => boolean;
|
|
46
|
+
readonly _requester: TBroadErrorHandler<ERR, RES>;
|
|
47
|
+
}
|
|
48
|
+
export interface IErrorHandleAttempt_Success<RES = void> {
|
|
49
|
+
handled: true;
|
|
50
|
+
result: RES;
|
|
51
|
+
target: TErrorHandlerTarget;
|
|
52
|
+
}
|
|
53
|
+
export interface IErrorHandleAttempt_Failure {
|
|
54
|
+
handled: false;
|
|
55
|
+
result?: undefined;
|
|
56
|
+
targets: TErrorHandlerTarget[];
|
|
57
|
+
}
|
|
58
|
+
export type TErrorHandleAttempt<RES = void> = IErrorHandleAttempt_Success<RES> | IErrorHandleAttempt_Failure;
|
|
59
|
+
export interface IHandleErrorOptions {
|
|
60
|
+
throwOnUnhandled?: boolean;
|
|
61
|
+
}
|
|
62
|
+
export type THandleErrorWithPromiseInspection<RES = void> = {
|
|
63
|
+
isPromise: false;
|
|
64
|
+
matched: true;
|
|
65
|
+
target: TErrorHandlerTarget;
|
|
66
|
+
handlerResponse: RES;
|
|
67
|
+
} | {
|
|
68
|
+
isPromise: true;
|
|
69
|
+
matched: true;
|
|
70
|
+
target: TErrorHandlerTarget;
|
|
71
|
+
handlerPromise: Promise<RES>;
|
|
72
|
+
} | {
|
|
73
|
+
matched: false;
|
|
74
|
+
attemptedTargets: TErrorHandlerTarget[];
|
|
75
|
+
};
|
|
76
|
+
export type THandleResponse<RES = unknown> = {
|
|
77
|
+
handled: false;
|
|
78
|
+
} | {
|
|
79
|
+
handled: true;
|
|
80
|
+
isPromise: boolean;
|
|
81
|
+
response: RES;
|
|
82
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { INiceErrorDomainProps, TDomainNiceErrorId } from "../NiceError/NiceError.types";
|
|
2
|
+
import type { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
|
|
3
|
+
import type { NiceErrorDomain } from "../NiceErrorDefined/NiceErrorDefined";
|
|
4
|
+
import { NiceErrorHandler } from "./NiceErrorHandler";
|
|
5
|
+
import type { MaybePromise } from "./NiceErrorHandler.types";
|
|
6
|
+
export declare function forDomain<DEF extends INiceErrorDomainProps, H_RES = void>(domain: NiceErrorDomain<DEF>, handler: (error: NiceErrorHydrated<DEF, TDomainNiceErrorId<DEF>>) => MaybePromise<H_RES>): NiceErrorHandler<never, H_RES>;
|
|
7
|
+
export declare function forId<DEF extends INiceErrorDomainProps, ID extends TDomainNiceErrorId<DEF>, H_RES = void>(domain: NiceErrorDomain<DEF>, id: ID, handler: (error: NiceErrorHydrated<DEF, ID>) => MaybePromise<H_RES>): NiceErrorHandler<never, H_RES>;
|
|
8
|
+
export declare function forIds<DEF extends INiceErrorDomainProps, IDS extends TDomainNiceErrorId<DEF>[], H_RES = void>(domain: NiceErrorDomain<DEF>, ids: IDS, handler: (error: NiceErrorHydrated<DEF, IDS[number]>) => MaybePromise<H_RES>): NiceErrorHandler<never, H_RES>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const err_example_app: import("..").
|
|
1
|
+
export declare const err_example_app: import("..").NiceErrorDomain<{
|
|
2
2
|
domain: "err_example_app";
|
|
3
3
|
allDomains: ["err_example_app"];
|
|
4
4
|
schema: {};
|
|
@@ -7,7 +7,7 @@ export declare enum EErrId_UserAuth {
|
|
|
7
7
|
invalid_credentials = "invalid_credentials",
|
|
8
8
|
account_locked = "account_locked"
|
|
9
9
|
}
|
|
10
|
-
export declare const err_user_auth: import("..").
|
|
10
|
+
export declare const err_user_auth: import("..").NiceErrorDomain<{
|
|
11
11
|
domain: string;
|
|
12
12
|
allDomains: [string, "err_example_app"];
|
|
13
13
|
schema: {
|
|
@@ -25,7 +25,7 @@ export declare enum EErrId_UserAuth_Registration {
|
|
|
25
25
|
password_error = "password_error",
|
|
26
26
|
password_too_short = "password_too_short"
|
|
27
27
|
}
|
|
28
|
-
export declare const err_user_auth_registration: import("..").
|
|
28
|
+
export declare const err_user_auth_registration: import("..").NiceErrorDomain<{
|
|
29
29
|
domain: string;
|
|
30
30
|
allDomains: [string, string, "err_example_app"];
|
|
31
31
|
schema: {
|
package/build/types/index.d.ts
CHANGED
|
@@ -5,9 +5,11 @@ export * from "./NiceError/NiceErrorHydrated";
|
|
|
5
5
|
export * from "./NiceErrorDefined/defineNiceError";
|
|
6
6
|
export * from "./NiceErrorDefined/err";
|
|
7
7
|
export * from "./NiceErrorDefined/NiceErrorDefined";
|
|
8
|
+
export * from "./NiceErrorHandler/handleWith";
|
|
9
|
+
export * from "./NiceErrorHandler/NiceErrorHandler";
|
|
10
|
+
export * from "./NiceErrorHandler/NiceErrorHandler.types";
|
|
8
11
|
export * from "./utils/castAndHydrate";
|
|
9
12
|
export * from "./utils/castNiceError";
|
|
10
|
-
export * from "./utils/handleWith";
|
|
11
13
|
export * from "./utils/isNiceErrorObject";
|
|
12
14
|
export * from "./utils/isRegularErrorObject";
|
|
13
15
|
export * from "./utils/matchFirst";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IInspectErrorResult_JsError, IInspectErrorResult_JsErrorObject, IInspectErrorResult_JsOther, IInspectErrorResult_Nullish, TInspectErrorResult_JsDataType } from "../utils/inspectPotentialError/inspectPotentialError.types";
|
|
2
|
-
export declare const err_nice: import("..").
|
|
2
|
+
export declare const err_nice: import("..").NiceErrorDomain<{
|
|
3
3
|
domain: "err_nice";
|
|
4
4
|
allDomains: ["err_nice"];
|
|
5
5
|
schema: {};
|
|
@@ -11,7 +11,7 @@ export declare enum EErrId_CastNotNice {
|
|
|
11
11
|
js_data_type = "js_data_type",
|
|
12
12
|
js_other = "js_other"
|
|
13
13
|
}
|
|
14
|
-
export declare const err_cast_not_nice: import("..").
|
|
14
|
+
export declare const err_cast_not_nice: import("..").NiceErrorDomain<{
|
|
15
15
|
domain: string;
|
|
16
16
|
allDomains: [string, "err_nice"];
|
|
17
17
|
schema: {
|
|
@@ -42,3 +42,8 @@ export declare const err_cast_not_nice: import("..").NiceErrorDefined<{
|
|
|
42
42
|
};
|
|
43
43
|
};
|
|
44
44
|
}>;
|
|
45
|
+
export declare const err_nice_handler: import("..").NiceErrorDomain<{
|
|
46
|
+
domain: string;
|
|
47
|
+
allDomains: [string, "err_nice"];
|
|
48
|
+
schema: {};
|
|
49
|
+
}>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { INiceErrorOptions } from "../../NiceError/NiceError";
|
|
2
|
-
import type {
|
|
3
|
-
export declare const nice_error_test_options: INiceErrorOptions<
|
|
2
|
+
import type { INiceErrorDomainProps } from "../../NiceError/NiceError.types";
|
|
3
|
+
export declare const nice_error_test_options: INiceErrorOptions<INiceErrorDomainProps, keyof INiceErrorDomainProps["schema"]>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NiceError } from "../NiceError/NiceError";
|
|
2
|
-
import type {
|
|
2
|
+
import type { INiceErrorDomainProps } from "../NiceError/NiceError.types";
|
|
3
3
|
import { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
|
|
4
|
-
import type {
|
|
4
|
+
import type { NiceErrorDomain } from "../NiceErrorDefined/NiceErrorDefined";
|
|
5
5
|
/**
|
|
6
6
|
* Combines `castNiceError`, `is()`, and `hydrate()` in a single call — the
|
|
7
7
|
* idiomatic way to handle an unknown value arriving from a remote boundary
|
|
@@ -32,4 +32,4 @@ import type { NiceErrorDefined } from "../NiceErrorDefined/NiceErrorDefined";
|
|
|
32
32
|
* });
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
export declare function castAndHydrate<ERR_DEF extends
|
|
35
|
+
export declare function castAndHydrate<ERR_DEF extends INiceErrorDomainProps>(value: unknown, niceErrorDefined: NiceErrorDomain<ERR_DEF>): NiceErrorHydrated<ERR_DEF, keyof ERR_DEF["schema"] & string> | NiceError;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { NiceError } from "../NiceError/NiceError";
|
|
2
|
-
import type {
|
|
2
|
+
import type { INiceErrorDomainProps, TExtractContextType } from "../NiceError/NiceError.types";
|
|
3
3
|
/**
|
|
4
4
|
* Handler map for `matchFirst`. Each key is an error id (from `ACTIVE_IDS`) and
|
|
5
5
|
* the value is a function that receives the typed context for that id.
|
|
6
6
|
*
|
|
7
7
|
* The `_` key is an optional fallback that runs when no id-specific handler matched.
|
|
8
8
|
*/
|
|
9
|
-
export type TMatchFirstHandlers<ERR_DEF extends
|
|
9
|
+
export type TMatchFirstHandlers<ERR_DEF extends INiceErrorDomainProps, ACTIVE_IDS extends keyof ERR_DEF["schema"] & string, RESULT> = {
|
|
10
10
|
[K in ACTIVE_IDS]?: (context: TExtractContextType<ERR_DEF["schema"][K]>) => RESULT;
|
|
11
11
|
} & {
|
|
12
12
|
_?: () => RESULT;
|
|
@@ -32,4 +32,4 @@ export type TMatchFirstHandlers<ERR_DEF extends INiceErrorDefinedProps, ACTIVE_I
|
|
|
32
32
|
* });
|
|
33
33
|
* ```
|
|
34
34
|
*/
|
|
35
|
-
export declare function matchFirst<ERR_DEF extends
|
|
35
|
+
export declare function matchFirst<ERR_DEF extends INiceErrorDomainProps, ACTIVE_IDS extends keyof ERR_DEF["schema"] & string, RESULT>(error: NiceError<ERR_DEF, ACTIVE_IDS>, handlers: TMatchFirstHandlers<ERR_DEF, ACTIVE_IDS, RESULT>): RESULT | undefined;
|
package/package.json
CHANGED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { INiceErrorDefinedProps } from "../NiceError/NiceError.types";
|
|
2
|
-
import type { NiceErrorHydrated } from "../NiceError/NiceErrorHydrated";
|
|
3
|
-
import type { NiceErrorDefined } from "../NiceErrorDefined/NiceErrorDefined";
|
|
4
|
-
/**
|
|
5
|
-
* A single case in a `handleWith` / `handleWithAsync` call.
|
|
6
|
-
*
|
|
7
|
-
* Construct via `forDomain` or `forIds` — do not build this object directly.
|
|
8
|
-
*/
|
|
9
|
-
export interface IErrorCase<DEF extends INiceErrorDefinedProps, IDS extends keyof DEF["schema"] & string> {
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Builds a case that fires for any error whose domain exactly matches `domain`.
|
|
13
|
-
* The handler receives the fully-hydrated error, narrowed to all schema ids.
|
|
14
|
-
*
|
|
15
|
-
* Use with `error.handleWith([...])` (sync) or `error.handleWithAsync([...])` (async).
|
|
16
|
-
*
|
|
17
|
-
* @example
|
|
18
|
-
* ```ts
|
|
19
|
-
* error.handleWith([
|
|
20
|
-
* forDomain(err_payments, (h) => {
|
|
21
|
-
* matchFirst(h, {
|
|
22
|
-
* payment_failed: ({ reason }) => res.status(402).json({ reason }),
|
|
23
|
-
* card_expired: () => res.status(402).json({ expired: true }),
|
|
24
|
-
* });
|
|
25
|
-
* }),
|
|
26
|
-
* ]);
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
|
-
export declare function forDomain<DEF extends INiceErrorDefinedProps>(domain: NiceErrorDefined<DEF>, handler: (error: NiceErrorHydrated<DEF, keyof DEF["schema"] & string>) => void | Promise<void>): IErrorCase<DEF, keyof DEF["schema"] & string>;
|
|
30
|
-
/**
|
|
31
|
-
* Builds a case that fires only if the error's domain matches `domain` **and**
|
|
32
|
-
* at least one of `ids` is active on the error.
|
|
33
|
-
* The handler receives the fully-hydrated error, narrowed to `IDS[number]`.
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* ```ts
|
|
37
|
-
* error.handleWith([
|
|
38
|
-
* forIds(err_feature, ["not_found", "forbidden"], (h) => {
|
|
39
|
-
* // h.getContext("not_found") and h.getContext("forbidden") are both available
|
|
40
|
-
* if (h.hasId("not_found")) res.status(404).json({ missing: h.getContext("not_found").resource });
|
|
41
|
-
* if (h.hasId("forbidden")) res.status(403).json({ denied: true });
|
|
42
|
-
* }),
|
|
43
|
-
*
|
|
44
|
-
* // Fallback: any other err_feature error
|
|
45
|
-
* forDomain(err_feature, (h) => res.status(500).json({ error: h.message })),
|
|
46
|
-
* ]);
|
|
47
|
-
* ```
|
|
48
|
-
*/
|
|
49
|
-
export declare function forIds<DEF extends INiceErrorDefinedProps, IDS extends ReadonlyArray<keyof DEF["schema"] & string>>(domain: NiceErrorDefined<DEF>, ids: IDS, handler: (error: NiceErrorHydrated<DEF, IDS[number]>) => void | Promise<void>): IErrorCase<DEF, IDS[number]>;
|