@bombillazo/error-x 0.2.0 → 0.2.2
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 +175 -1
- package/dist/index.cjs +402 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +475 -1
- package/dist/index.d.ts +475 -1
- package/dist/index.js +402 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -207,6 +207,10 @@ type ErrorXOptions = {
|
|
|
207
207
|
metadata?: ErrorMetadata;
|
|
208
208
|
/** Actions to perform when this error occurs (default: undefined) */
|
|
209
209
|
actions?: ErrorAction[];
|
|
210
|
+
/** HTTP status code (100-599) for HTTP-related errors (default: undefined) */
|
|
211
|
+
httpStatus?: number | undefined;
|
|
212
|
+
/** Error type for categorization */
|
|
213
|
+
type?: string | undefined;
|
|
210
214
|
};
|
|
211
215
|
/**
|
|
212
216
|
* JSON-serializable representation of an ErrorX instance.
|
|
@@ -255,6 +259,10 @@ type SerializableError = {
|
|
|
255
259
|
actions?: ErrorAction[];
|
|
256
260
|
/** Serialized cause error (for error chaining) */
|
|
257
261
|
cause?: SerializableError;
|
|
262
|
+
/** HTTP status code for HTTP-related errors */
|
|
263
|
+
httpStatus?: number;
|
|
264
|
+
/** Error type for categorization */
|
|
265
|
+
type?: string;
|
|
258
266
|
};
|
|
259
267
|
|
|
260
268
|
/**
|
|
@@ -288,6 +296,10 @@ declare class ErrorX extends Error {
|
|
|
288
296
|
readonly timestamp: Date;
|
|
289
297
|
/** Error actions for UI behavior and handling */
|
|
290
298
|
readonly actions: ErrorAction[] | undefined;
|
|
299
|
+
/** HTTP status code (100-599) for HTTP-related errors */
|
|
300
|
+
readonly httpStatus: number | undefined;
|
|
301
|
+
/** Error type for categorization */
|
|
302
|
+
readonly type: string | undefined;
|
|
291
303
|
/**
|
|
292
304
|
* Creates a new ErrorX instance with enhanced error handling capabilities.
|
|
293
305
|
*
|
|
@@ -331,6 +343,20 @@ declare class ErrorX extends Error {
|
|
|
331
343
|
* @returns Default error name 'Error'
|
|
332
344
|
*/
|
|
333
345
|
private static getDefaultName;
|
|
346
|
+
/**
|
|
347
|
+
* Validates HTTP status code to ensure it's within valid range (100-599)
|
|
348
|
+
*
|
|
349
|
+
* @param status - Status code to validate
|
|
350
|
+
* @returns Valid status code or undefined if invalid/not provided
|
|
351
|
+
*/
|
|
352
|
+
private static validateHttpStatus;
|
|
353
|
+
/**
|
|
354
|
+
* Validates and normalizes the type field
|
|
355
|
+
*
|
|
356
|
+
* @param type - Type value to validate
|
|
357
|
+
* @returns Validated type string or undefined if invalid/empty
|
|
358
|
+
*/
|
|
359
|
+
private static validateType;
|
|
334
360
|
/**
|
|
335
361
|
* Validates if an object is a valid ErrorXOptions object.
|
|
336
362
|
* Checks that the object only contains accepted ErrorXOptions fields.
|
|
@@ -572,4 +598,452 @@ declare class ErrorX extends Error {
|
|
|
572
598
|
static fromJSON(serialized: SerializableError): ErrorX;
|
|
573
599
|
}
|
|
574
600
|
|
|
575
|
-
|
|
601
|
+
/**
|
|
602
|
+
* Preset configurations for common errors organized by category.
|
|
603
|
+
*
|
|
604
|
+
* ## Features
|
|
605
|
+
* - **Pre-configured error templates** for common HTTP status codes (400-511)
|
|
606
|
+
* - **Type-safe** with TypeScript support
|
|
607
|
+
* - **Fully customizable** via destructuring and override pattern
|
|
608
|
+
* - **User-friendly messages** included for all presets
|
|
609
|
+
* - **Categorized by type** - all HTTP presets include `type: 'http'`
|
|
610
|
+
*
|
|
611
|
+
* ## Available Categories
|
|
612
|
+
* - **HTTP**: Common HTTP status codes (4xx client errors, 5xx server errors)
|
|
613
|
+
*
|
|
614
|
+
* ## Usage Patterns
|
|
615
|
+
*
|
|
616
|
+
* ### 1. Direct Usage
|
|
617
|
+
* Use a preset as-is without any modifications:
|
|
618
|
+
* ```typescript
|
|
619
|
+
* import { ErrorX, PRESETS } from '@bombillazo/error-x'
|
|
620
|
+
*
|
|
621
|
+
* throw new ErrorX(PRESETS.HTTP.NOT_FOUND)
|
|
622
|
+
* // Result: 404 error with default message and UI message
|
|
623
|
+
* ```
|
|
624
|
+
*
|
|
625
|
+
* ### 2. Override Specific Fields
|
|
626
|
+
* Customize the error while keeping other preset values:
|
|
627
|
+
* ```typescript
|
|
628
|
+
* throw new ErrorX({
|
|
629
|
+
* ...PRESETS.HTTP.NOT_FOUND,
|
|
630
|
+
* message: 'User not found',
|
|
631
|
+
* metadata: { userId: 123 }
|
|
632
|
+
* })
|
|
633
|
+
* // Result: 404 error with custom message but keeps httpStatus, code, name, uiMessage, type
|
|
634
|
+
* ```
|
|
635
|
+
*
|
|
636
|
+
* ### 3. Add Metadata and Actions
|
|
637
|
+
* Enhance presets with additional context and behaviors:
|
|
638
|
+
* ```typescript
|
|
639
|
+
* throw new ErrorX({
|
|
640
|
+
* ...PRESETS.HTTP.UNAUTHORIZED,
|
|
641
|
+
* metadata: { attemptedAction: 'viewProfile', userId: 456 },
|
|
642
|
+
* actions: [
|
|
643
|
+
* { action: 'logout', payload: { clearStorage: true } },
|
|
644
|
+
* { action: 'redirect', payload: { redirectURL: '/login' } }
|
|
645
|
+
* ]
|
|
646
|
+
* })
|
|
647
|
+
* ```
|
|
648
|
+
*
|
|
649
|
+
* ### 4. Add Error Cause
|
|
650
|
+
* Chain errors by adding a cause:
|
|
651
|
+
* ```typescript
|
|
652
|
+
* try {
|
|
653
|
+
* // some operation
|
|
654
|
+
* } catch (originalError) {
|
|
655
|
+
* throw new ErrorX({
|
|
656
|
+
* ...PRESETS.HTTP.INTERNAL_SERVER_ERROR,
|
|
657
|
+
* cause: originalError,
|
|
658
|
+
* metadata: { operation: 'database-query' }
|
|
659
|
+
* })
|
|
660
|
+
* }
|
|
661
|
+
* ```
|
|
662
|
+
*
|
|
663
|
+
* ## Common HTTP Presets
|
|
664
|
+
*
|
|
665
|
+
* ### 4xx Client Errors
|
|
666
|
+
* - `BAD_REQUEST` (400) - Invalid request data
|
|
667
|
+
* - `UNAUTHORIZED` (401) - Authentication required
|
|
668
|
+
* - `FORBIDDEN` (403) - Insufficient permissions
|
|
669
|
+
* - `NOT_FOUND` (404) - Resource not found
|
|
670
|
+
* - `METHOD_NOT_ALLOWED` (405) - HTTP method not allowed
|
|
671
|
+
* - `CONFLICT` (409) - Resource conflict
|
|
672
|
+
* - `UNPROCESSABLE_ENTITY` (422) - Validation failed
|
|
673
|
+
* - `TOO_MANY_REQUESTS` (429) - Rate limit exceeded
|
|
674
|
+
*
|
|
675
|
+
* ### 5xx Server Errors
|
|
676
|
+
* - `INTERNAL_SERVER_ERROR` (500) - Unexpected server error
|
|
677
|
+
* - `NOT_IMPLEMENTED` (501) - Feature not implemented
|
|
678
|
+
* - `BAD_GATEWAY` (502) - Upstream server error
|
|
679
|
+
* - `SERVICE_UNAVAILABLE` (503) - Service temporarily down
|
|
680
|
+
* - `GATEWAY_TIMEOUT` (504) - Upstream timeout
|
|
681
|
+
*
|
|
682
|
+
* @example
|
|
683
|
+
* ```typescript
|
|
684
|
+
* import { ErrorX, PRESETS } from '@bombillazo/error-x'
|
|
685
|
+
*
|
|
686
|
+
* // API endpoint example
|
|
687
|
+
* app.get('/users/:id', async (req, res) => {
|
|
688
|
+
* const user = await db.users.findById(req.params.id)
|
|
689
|
+
*
|
|
690
|
+
* if (!user) {
|
|
691
|
+
* throw new ErrorX({
|
|
692
|
+
* ...PRESETS.HTTP.NOT_FOUND,
|
|
693
|
+
* message: 'User not found',
|
|
694
|
+
* metadata: { userId: req.params.id }
|
|
695
|
+
* })
|
|
696
|
+
* }
|
|
697
|
+
*
|
|
698
|
+
* res.json(user)
|
|
699
|
+
* })
|
|
700
|
+
*
|
|
701
|
+
* // Authentication middleware example
|
|
702
|
+
* const requireAuth = (req, res, next) => {
|
|
703
|
+
* if (!req.user) {
|
|
704
|
+
* throw new ErrorX({
|
|
705
|
+
* ...PRESETS.HTTP.UNAUTHORIZED,
|
|
706
|
+
* actions: [
|
|
707
|
+
* { action: 'redirect', payload: { redirectURL: '/login' } }
|
|
708
|
+
* ]
|
|
709
|
+
* })
|
|
710
|
+
* }
|
|
711
|
+
* next()
|
|
712
|
+
* }
|
|
713
|
+
*
|
|
714
|
+
* // Rate limiting example
|
|
715
|
+
* if (isRateLimited(req.ip)) {
|
|
716
|
+
* throw new ErrorX({
|
|
717
|
+
* ...PRESETS.HTTP.TOO_MANY_REQUESTS,
|
|
718
|
+
* metadata: {
|
|
719
|
+
* ip: req.ip,
|
|
720
|
+
* retryAfter: 60
|
|
721
|
+
* }
|
|
722
|
+
* })
|
|
723
|
+
* }
|
|
724
|
+
* ```
|
|
725
|
+
*
|
|
726
|
+
* @public
|
|
727
|
+
*/
|
|
728
|
+
declare const PRESETS: {
|
|
729
|
+
/**
|
|
730
|
+
* HTTP error presets for common HTTP status codes.
|
|
731
|
+
* Includes both 4xx client errors and 5xx server errors.
|
|
732
|
+
*/
|
|
733
|
+
readonly HTTP: {
|
|
734
|
+
readonly BAD_REQUEST: {
|
|
735
|
+
httpStatus: number;
|
|
736
|
+
code: string;
|
|
737
|
+
name: string;
|
|
738
|
+
message: string;
|
|
739
|
+
uiMessage: string;
|
|
740
|
+
type: string;
|
|
741
|
+
};
|
|
742
|
+
readonly UNAUTHORIZED: {
|
|
743
|
+
httpStatus: number;
|
|
744
|
+
code: string;
|
|
745
|
+
name: string;
|
|
746
|
+
message: string;
|
|
747
|
+
uiMessage: string;
|
|
748
|
+
type: string;
|
|
749
|
+
};
|
|
750
|
+
readonly PAYMENT_REQUIRED: {
|
|
751
|
+
httpStatus: number;
|
|
752
|
+
code: string;
|
|
753
|
+
name: string;
|
|
754
|
+
message: string;
|
|
755
|
+
uiMessage: string;
|
|
756
|
+
type: string;
|
|
757
|
+
};
|
|
758
|
+
readonly FORBIDDEN: {
|
|
759
|
+
httpStatus: number;
|
|
760
|
+
code: string;
|
|
761
|
+
name: string;
|
|
762
|
+
message: string;
|
|
763
|
+
uiMessage: string;
|
|
764
|
+
type: string;
|
|
765
|
+
};
|
|
766
|
+
readonly NOT_FOUND: {
|
|
767
|
+
httpStatus: number;
|
|
768
|
+
code: string;
|
|
769
|
+
name: string;
|
|
770
|
+
message: string;
|
|
771
|
+
uiMessage: string;
|
|
772
|
+
type: string;
|
|
773
|
+
};
|
|
774
|
+
readonly METHOD_NOT_ALLOWED: {
|
|
775
|
+
httpStatus: number;
|
|
776
|
+
code: string;
|
|
777
|
+
name: string;
|
|
778
|
+
message: string;
|
|
779
|
+
uiMessage: string;
|
|
780
|
+
type: string;
|
|
781
|
+
};
|
|
782
|
+
readonly NOT_ACCEPTABLE: {
|
|
783
|
+
httpStatus: number;
|
|
784
|
+
code: string;
|
|
785
|
+
name: string;
|
|
786
|
+
message: string;
|
|
787
|
+
uiMessage: string;
|
|
788
|
+
type: string;
|
|
789
|
+
};
|
|
790
|
+
readonly PROXY_AUTHENTICATION_REQUIRED: {
|
|
791
|
+
httpStatus: number;
|
|
792
|
+
code: string;
|
|
793
|
+
name: string;
|
|
794
|
+
message: string;
|
|
795
|
+
uiMessage: string;
|
|
796
|
+
type: string;
|
|
797
|
+
};
|
|
798
|
+
readonly REQUEST_TIMEOUT: {
|
|
799
|
+
httpStatus: number;
|
|
800
|
+
code: string;
|
|
801
|
+
name: string;
|
|
802
|
+
message: string;
|
|
803
|
+
uiMessage: string;
|
|
804
|
+
type: string;
|
|
805
|
+
};
|
|
806
|
+
readonly CONFLICT: {
|
|
807
|
+
httpStatus: number;
|
|
808
|
+
code: string;
|
|
809
|
+
name: string;
|
|
810
|
+
message: string;
|
|
811
|
+
uiMessage: string;
|
|
812
|
+
type: string;
|
|
813
|
+
};
|
|
814
|
+
readonly GONE: {
|
|
815
|
+
httpStatus: number;
|
|
816
|
+
code: string;
|
|
817
|
+
name: string;
|
|
818
|
+
message: string;
|
|
819
|
+
uiMessage: string;
|
|
820
|
+
type: string;
|
|
821
|
+
};
|
|
822
|
+
readonly LENGTH_REQUIRED: {
|
|
823
|
+
httpStatus: number;
|
|
824
|
+
code: string;
|
|
825
|
+
name: string;
|
|
826
|
+
message: string;
|
|
827
|
+
uiMessage: string;
|
|
828
|
+
type: string;
|
|
829
|
+
};
|
|
830
|
+
readonly PRECONDITION_FAILED: {
|
|
831
|
+
httpStatus: number;
|
|
832
|
+
code: string;
|
|
833
|
+
name: string;
|
|
834
|
+
message: string;
|
|
835
|
+
uiMessage: string;
|
|
836
|
+
type: string;
|
|
837
|
+
};
|
|
838
|
+
readonly PAYLOAD_TOO_LARGE: {
|
|
839
|
+
httpStatus: number;
|
|
840
|
+
code: string;
|
|
841
|
+
name: string;
|
|
842
|
+
message: string;
|
|
843
|
+
uiMessage: string;
|
|
844
|
+
type: string;
|
|
845
|
+
};
|
|
846
|
+
readonly URI_TOO_LONG: {
|
|
847
|
+
httpStatus: number;
|
|
848
|
+
code: string;
|
|
849
|
+
name: string;
|
|
850
|
+
message: string;
|
|
851
|
+
uiMessage: string;
|
|
852
|
+
type: string;
|
|
853
|
+
};
|
|
854
|
+
readonly UNSUPPORTED_MEDIA_TYPE: {
|
|
855
|
+
httpStatus: number;
|
|
856
|
+
code: string;
|
|
857
|
+
name: string;
|
|
858
|
+
message: string;
|
|
859
|
+
uiMessage: string;
|
|
860
|
+
type: string;
|
|
861
|
+
};
|
|
862
|
+
readonly RANGE_NOT_SATISFIABLE: {
|
|
863
|
+
httpStatus: number;
|
|
864
|
+
code: string;
|
|
865
|
+
name: string;
|
|
866
|
+
message: string;
|
|
867
|
+
uiMessage: string;
|
|
868
|
+
type: string;
|
|
869
|
+
};
|
|
870
|
+
readonly EXPECTATION_FAILED: {
|
|
871
|
+
httpStatus: number;
|
|
872
|
+
code: string;
|
|
873
|
+
name: string;
|
|
874
|
+
message: string;
|
|
875
|
+
uiMessage: string;
|
|
876
|
+
type: string;
|
|
877
|
+
};
|
|
878
|
+
readonly IM_A_TEAPOT: {
|
|
879
|
+
httpStatus: number;
|
|
880
|
+
code: string;
|
|
881
|
+
name: string;
|
|
882
|
+
message: string;
|
|
883
|
+
uiMessage: string;
|
|
884
|
+
type: string;
|
|
885
|
+
};
|
|
886
|
+
readonly UNPROCESSABLE_ENTITY: {
|
|
887
|
+
httpStatus: number;
|
|
888
|
+
code: string;
|
|
889
|
+
name: string;
|
|
890
|
+
message: string;
|
|
891
|
+
uiMessage: string;
|
|
892
|
+
type: string;
|
|
893
|
+
};
|
|
894
|
+
readonly LOCKED: {
|
|
895
|
+
httpStatus: number;
|
|
896
|
+
code: string;
|
|
897
|
+
name: string;
|
|
898
|
+
message: string;
|
|
899
|
+
uiMessage: string;
|
|
900
|
+
type: string;
|
|
901
|
+
};
|
|
902
|
+
readonly FAILED_DEPENDENCY: {
|
|
903
|
+
httpStatus: number;
|
|
904
|
+
code: string;
|
|
905
|
+
name: string;
|
|
906
|
+
message: string;
|
|
907
|
+
uiMessage: string;
|
|
908
|
+
type: string;
|
|
909
|
+
};
|
|
910
|
+
readonly TOO_EARLY: {
|
|
911
|
+
httpStatus: number;
|
|
912
|
+
code: string;
|
|
913
|
+
name: string;
|
|
914
|
+
message: string;
|
|
915
|
+
uiMessage: string;
|
|
916
|
+
type: string;
|
|
917
|
+
};
|
|
918
|
+
readonly UPGRADE_REQUIRED: {
|
|
919
|
+
httpStatus: number;
|
|
920
|
+
code: string;
|
|
921
|
+
name: string;
|
|
922
|
+
message: string;
|
|
923
|
+
uiMessage: string;
|
|
924
|
+
type: string;
|
|
925
|
+
};
|
|
926
|
+
readonly PRECONDITION_REQUIRED: {
|
|
927
|
+
httpStatus: number;
|
|
928
|
+
code: string;
|
|
929
|
+
name: string;
|
|
930
|
+
message: string;
|
|
931
|
+
uiMessage: string;
|
|
932
|
+
type: string;
|
|
933
|
+
};
|
|
934
|
+
readonly TOO_MANY_REQUESTS: {
|
|
935
|
+
httpStatus: number;
|
|
936
|
+
code: string;
|
|
937
|
+
name: string;
|
|
938
|
+
message: string;
|
|
939
|
+
uiMessage: string;
|
|
940
|
+
type: string;
|
|
941
|
+
};
|
|
942
|
+
readonly REQUEST_HEADER_FIELDS_TOO_LARGE: {
|
|
943
|
+
httpStatus: number;
|
|
944
|
+
code: string;
|
|
945
|
+
name: string;
|
|
946
|
+
message: string;
|
|
947
|
+
uiMessage: string;
|
|
948
|
+
type: string;
|
|
949
|
+
};
|
|
950
|
+
readonly UNAVAILABLE_FOR_LEGAL_REASONS: {
|
|
951
|
+
httpStatus: number;
|
|
952
|
+
code: string;
|
|
953
|
+
name: string;
|
|
954
|
+
message: string;
|
|
955
|
+
uiMessage: string;
|
|
956
|
+
type: string;
|
|
957
|
+
};
|
|
958
|
+
readonly INTERNAL_SERVER_ERROR: {
|
|
959
|
+
httpStatus: number;
|
|
960
|
+
code: string;
|
|
961
|
+
name: string;
|
|
962
|
+
message: string;
|
|
963
|
+
uiMessage: string;
|
|
964
|
+
type: string;
|
|
965
|
+
};
|
|
966
|
+
readonly NOT_IMPLEMENTED: {
|
|
967
|
+
httpStatus: number;
|
|
968
|
+
code: string;
|
|
969
|
+
name: string;
|
|
970
|
+
message: string;
|
|
971
|
+
uiMessage: string;
|
|
972
|
+
type: string;
|
|
973
|
+
};
|
|
974
|
+
readonly BAD_GATEWAY: {
|
|
975
|
+
httpStatus: number;
|
|
976
|
+
code: string;
|
|
977
|
+
name: string;
|
|
978
|
+
message: string;
|
|
979
|
+
uiMessage: string;
|
|
980
|
+
type: string;
|
|
981
|
+
};
|
|
982
|
+
readonly SERVICE_UNAVAILABLE: {
|
|
983
|
+
httpStatus: number;
|
|
984
|
+
code: string;
|
|
985
|
+
name: string;
|
|
986
|
+
message: string;
|
|
987
|
+
uiMessage: string;
|
|
988
|
+
type: string;
|
|
989
|
+
};
|
|
990
|
+
readonly GATEWAY_TIMEOUT: {
|
|
991
|
+
httpStatus: number;
|
|
992
|
+
code: string;
|
|
993
|
+
name: string;
|
|
994
|
+
message: string;
|
|
995
|
+
uiMessage: string;
|
|
996
|
+
type: string;
|
|
997
|
+
};
|
|
998
|
+
readonly HTTP_VERSION_NOT_SUPPORTED: {
|
|
999
|
+
httpStatus: number;
|
|
1000
|
+
code: string;
|
|
1001
|
+
name: string;
|
|
1002
|
+
message: string;
|
|
1003
|
+
uiMessage: string;
|
|
1004
|
+
type: string;
|
|
1005
|
+
};
|
|
1006
|
+
readonly VARIANT_ALSO_NEGOTIATES: {
|
|
1007
|
+
httpStatus: number;
|
|
1008
|
+
code: string;
|
|
1009
|
+
name: string;
|
|
1010
|
+
message: string;
|
|
1011
|
+
uiMessage: string;
|
|
1012
|
+
type: string;
|
|
1013
|
+
};
|
|
1014
|
+
readonly INSUFFICIENT_STORAGE: {
|
|
1015
|
+
httpStatus: number;
|
|
1016
|
+
code: string;
|
|
1017
|
+
name: string;
|
|
1018
|
+
message: string;
|
|
1019
|
+
uiMessage: string;
|
|
1020
|
+
type: string;
|
|
1021
|
+
};
|
|
1022
|
+
readonly LOOP_DETECTED: {
|
|
1023
|
+
httpStatus: number;
|
|
1024
|
+
code: string;
|
|
1025
|
+
name: string;
|
|
1026
|
+
message: string;
|
|
1027
|
+
uiMessage: string;
|
|
1028
|
+
type: string;
|
|
1029
|
+
};
|
|
1030
|
+
readonly NOT_EXTENDED: {
|
|
1031
|
+
httpStatus: number;
|
|
1032
|
+
code: string;
|
|
1033
|
+
name: string;
|
|
1034
|
+
message: string;
|
|
1035
|
+
uiMessage: string;
|
|
1036
|
+
type: string;
|
|
1037
|
+
};
|
|
1038
|
+
readonly NETWORK_AUTHENTICATION_REQUIRED: {
|
|
1039
|
+
httpStatus: number;
|
|
1040
|
+
code: string;
|
|
1041
|
+
name: string;
|
|
1042
|
+
message: string;
|
|
1043
|
+
uiMessage: string;
|
|
1044
|
+
type: string;
|
|
1045
|
+
};
|
|
1046
|
+
};
|
|
1047
|
+
};
|
|
1048
|
+
|
|
1049
|
+
export { type CustomAction, type ErrorAction, type ErrorMetadata, ErrorX, type ErrorXOptions, type HandlingTarget, HandlingTargets, type LogoutAction, type NotifyAction, PRESETS, type RedirectAction, type SerializableError };
|