@bombillazo/error-x 0.2.1 → 0.3.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/dist/index.js CHANGED
@@ -646,132 +646,244 @@ ${this.stack}`;
646
646
  }
647
647
  return error;
648
648
  }
649
- };
650
-
651
- // src/presets.ts
652
- var PRESETS = {
653
649
  /**
654
650
  * HTTP error presets for common HTTP status codes.
655
- * Includes both 4xx client errors and 5xx server errors.
651
+ *
652
+ * ## Features
653
+ * - **Pre-configured error templates** for common HTTP status codes (400-511)
654
+ * - **Type-safe** with TypeScript support
655
+ * - **Fully customizable** via destructuring and override pattern
656
+ * - **User-friendly messages** included for all presets
657
+ * - **Categorized by type** - all HTTP presets include `type: 'http'`
658
+ *
659
+ * ## Usage Patterns
660
+ *
661
+ * ### 1. Direct Usage
662
+ * Use a preset as-is without any modifications:
663
+ * ```typescript
664
+ * throw new ErrorX(ErrorX.HTTP.NOT_FOUND)
665
+ * // Result: 404 error with default message and UI message
666
+ * ```
667
+ *
668
+ * ### 2. Override Specific Fields
669
+ * Customize the error while keeping other preset values:
670
+ * ```typescript
671
+ * throw new ErrorX({
672
+ * ...ErrorX.HTTP.NOT_FOUND,
673
+ * message: 'User not found',
674
+ * metadata: { userId: 123 }
675
+ * })
676
+ * // Result: 404 error with custom message but keeps httpStatus, code, name, uiMessage, type
677
+ * ```
678
+ *
679
+ * ### 3. Add Metadata and Actions
680
+ * Enhance presets with additional context and behaviors:
681
+ * ```typescript
682
+ * throw new ErrorX({
683
+ * ...ErrorX.HTTP.UNAUTHORIZED,
684
+ * metadata: { attemptedAction: 'viewProfile', userId: 456 },
685
+ * actions: [
686
+ * { action: 'logout', payload: { clearStorage: true } },
687
+ * { action: 'redirect', payload: { redirectURL: '/login' } }
688
+ * ]
689
+ * })
690
+ * ```
691
+ *
692
+ * ### 4. Add Error Cause
693
+ * Chain errors by adding a cause:
694
+ * ```typescript
695
+ * try {
696
+ * // some operation
697
+ * } catch (originalError) {
698
+ * throw new ErrorX({
699
+ * ...ErrorX.HTTP.INTERNAL_SERVER_ERROR,
700
+ * cause: originalError,
701
+ * metadata: { operation: 'database-query' }
702
+ * })
703
+ * }
704
+ * ```
705
+ *
706
+ * ## Common HTTP Presets
707
+ *
708
+ * ### 4xx Client Errors
709
+ * - `BAD_REQUEST` (400) - Invalid request data
710
+ * - `UNAUTHORIZED` (401) - Authentication required
711
+ * - `FORBIDDEN` (403) - Insufficient permissions
712
+ * - `NOT_FOUND` (404) - Resource not found
713
+ * - `METHOD_NOT_ALLOWED` (405) - HTTP method not allowed
714
+ * - `CONFLICT` (409) - Resource conflict
715
+ * - `UNPROCESSABLE_ENTITY` (422) - Validation failed
716
+ * - `TOO_MANY_REQUESTS` (429) - Rate limit exceeded
717
+ *
718
+ * ### 5xx Server Errors
719
+ * - `INTERNAL_SERVER_ERROR` (500) - Unexpected server error
720
+ * - `NOT_IMPLEMENTED` (501) - Feature not implemented
721
+ * - `BAD_GATEWAY` (502) - Upstream server error
722
+ * - `SERVICE_UNAVAILABLE` (503) - Service temporarily down
723
+ * - `GATEWAY_TIMEOUT` (504) - Upstream timeout
724
+ *
725
+ * @example
726
+ * ```typescript
727
+ * // API endpoint example
728
+ * app.get('/users/:id', async (req, res) => {
729
+ * const user = await db.users.findById(req.params.id)
730
+ *
731
+ * if (!user) {
732
+ * throw new ErrorX({
733
+ * ...ErrorX.HTTP.NOT_FOUND,
734
+ * message: 'User not found',
735
+ * metadata: { userId: req.params.id }
736
+ * })
737
+ * }
738
+ *
739
+ * res.json(user)
740
+ * })
741
+ *
742
+ * // Authentication middleware example
743
+ * const requireAuth = (req, res, next) => {
744
+ * if (!req.user) {
745
+ * throw new ErrorX({
746
+ * ...ErrorX.HTTP.UNAUTHORIZED,
747
+ * actions: [
748
+ * { action: 'redirect', payload: { redirectURL: '/login' } }
749
+ * ]
750
+ * })
751
+ * }
752
+ * next()
753
+ * }
754
+ *
755
+ * // Rate limiting example
756
+ * if (isRateLimited(req.ip)) {
757
+ * throw new ErrorX({
758
+ * ...ErrorX.HTTP.TOO_MANY_REQUESTS,
759
+ * metadata: {
760
+ * ip: req.ip,
761
+ * retryAfter: 60
762
+ * }
763
+ * })
764
+ * }
765
+ * ```
766
+ *
767
+ * @public
656
768
  */
657
- HTTP: {
769
+ static HTTP = {
658
770
  // 4xx Client Errors
659
771
  BAD_REQUEST: {
660
772
  httpStatus: 400,
661
773
  code: "BAD_REQUEST",
662
- name: "BadRequestError",
663
- message: "Bad request",
774
+ name: "Bad Request Error",
775
+ message: "bad request",
664
776
  uiMessage: "The request could not be processed. Please check your input and try again.",
665
777
  type: "http"
666
778
  },
667
779
  UNAUTHORIZED: {
668
780
  httpStatus: 401,
669
781
  code: "UNAUTHORIZED",
670
- name: "UnauthorizedError",
671
- message: "Unauthorized",
782
+ name: "Unauthorized Error",
783
+ message: "unauthorized",
672
784
  uiMessage: "Authentication required. Please log in to continue.",
673
785
  type: "http"
674
786
  },
675
787
  PAYMENT_REQUIRED: {
676
788
  httpStatus: 402,
677
789
  code: "PAYMENT_REQUIRED",
678
- name: "PaymentRequiredError",
679
- message: "Payment required",
790
+ name: "Payment Required Error",
791
+ message: "payment required",
680
792
  uiMessage: "Payment is required to access this resource.",
681
793
  type: "http"
682
794
  },
683
795
  FORBIDDEN: {
684
796
  httpStatus: 403,
685
797
  code: "FORBIDDEN",
686
- name: "ForbiddenError",
687
- message: "Forbidden",
798
+ name: "Forbidden Error",
799
+ message: "forbidden",
688
800
  uiMessage: "You do not have permission to access this resource.",
689
801
  type: "http"
690
802
  },
691
803
  NOT_FOUND: {
692
804
  httpStatus: 404,
693
805
  code: "NOT_FOUND",
694
- name: "NotFoundError",
695
- message: "Not found",
806
+ name: "Not Found Error",
807
+ message: "not found",
696
808
  uiMessage: "The requested resource could not be found.",
697
809
  type: "http"
698
810
  },
699
811
  METHOD_NOT_ALLOWED: {
700
812
  httpStatus: 405,
701
813
  code: "METHOD_NOT_ALLOWED",
702
- name: "MethodNotAllowedError",
703
- message: "Method not allowed",
814
+ name: "Method Not Allowed Error",
815
+ message: "method not allowed",
704
816
  uiMessage: "This action is not allowed for the requested resource.",
705
817
  type: "http"
706
818
  },
707
819
  NOT_ACCEPTABLE: {
708
820
  httpStatus: 406,
709
821
  code: "NOT_ACCEPTABLE",
710
- name: "NotAcceptableError",
711
- message: "Not acceptable",
822
+ name: "Not Acceptable Error",
823
+ message: "not acceptable",
712
824
  uiMessage: "The requested format is not supported.",
713
825
  type: "http"
714
826
  },
715
827
  PROXY_AUTHENTICATION_REQUIRED: {
716
828
  httpStatus: 407,
717
829
  code: "PROXY_AUTHENTICATION_REQUIRED",
718
- name: "ProxyAuthenticationRequiredError",
719
- message: "Proxy authentication required",
830
+ name: "Proxy Authentication Required Error",
831
+ message: "proxy authentication required",
720
832
  uiMessage: "Proxy authentication is required to access this resource.",
721
833
  type: "http"
722
834
  },
723
835
  REQUEST_TIMEOUT: {
724
836
  httpStatus: 408,
725
837
  code: "REQUEST_TIMEOUT",
726
- name: "RequestTimeoutError",
727
- message: "Request timeout",
838
+ name: "Request Timeout Error",
839
+ message: "request timeout",
728
840
  uiMessage: "The request took too long to complete. Please try again.",
729
841
  type: "http"
730
842
  },
731
843
  CONFLICT: {
732
844
  httpStatus: 409,
733
845
  code: "CONFLICT",
734
- name: "ConflictError",
735
- message: "Conflict",
846
+ name: "Conflict Error",
847
+ message: "conflict",
736
848
  uiMessage: "The request conflicts with the current state. Please refresh and try again.",
737
849
  type: "http"
738
850
  },
739
851
  GONE: {
740
852
  httpStatus: 410,
741
853
  code: "GONE",
742
- name: "GoneError",
743
- message: "Gone",
854
+ name: "Gone Error",
855
+ message: "gone",
744
856
  uiMessage: "This resource is no longer available.",
745
857
  type: "http"
746
858
  },
747
859
  LENGTH_REQUIRED: {
748
860
  httpStatus: 411,
749
861
  code: "LENGTH_REQUIRED",
750
- name: "LengthRequiredError",
751
- message: "Length required",
862
+ name: "Length Required Error",
863
+ message: "length required",
752
864
  uiMessage: "The request is missing required length information.",
753
865
  type: "http"
754
866
  },
755
867
  PRECONDITION_FAILED: {
756
868
  httpStatus: 412,
757
869
  code: "PRECONDITION_FAILED",
758
- name: "PreconditionFailedError",
759
- message: "Precondition failed",
870
+ name: "Precondition Failed Error",
871
+ message: "precondition failed",
760
872
  uiMessage: "A required condition was not met. Please try again.",
761
873
  type: "http"
762
874
  },
763
875
  PAYLOAD_TOO_LARGE: {
764
876
  httpStatus: 413,
765
877
  code: "PAYLOAD_TOO_LARGE",
766
- name: "PayloadTooLargeError",
767
- message: "Payload too large",
878
+ name: "Payload Too Large Error",
879
+ message: "payload too large",
768
880
  uiMessage: "The request is too large. Please reduce the size and try again.",
769
881
  type: "http"
770
882
  },
771
883
  URI_TOO_LONG: {
772
884
  httpStatus: 414,
773
885
  code: "URI_TOO_LONG",
774
- name: "URITooLongError",
886
+ name: "URI Too Long Error",
775
887
  message: "URI too long",
776
888
  uiMessage: "The request URL is too long.",
777
889
  type: "http"
@@ -779,104 +891,104 @@ var PRESETS = {
779
891
  UNSUPPORTED_MEDIA_TYPE: {
780
892
  httpStatus: 415,
781
893
  code: "UNSUPPORTED_MEDIA_TYPE",
782
- name: "UnsupportedMediaTypeError",
783
- message: "Unsupported media type",
894
+ name: "Unsupported Media Type Error",
895
+ message: "unsupported media type",
784
896
  uiMessage: "The file type is not supported.",
785
897
  type: "http"
786
898
  },
787
899
  RANGE_NOT_SATISFIABLE: {
788
900
  httpStatus: 416,
789
901
  code: "RANGE_NOT_SATISFIABLE",
790
- name: "RangeNotSatisfiableError",
791
- message: "Range not satisfiable",
902
+ name: "Range Not Satisfiable Error",
903
+ message: "range not satisfiable",
792
904
  uiMessage: "The requested range cannot be satisfied.",
793
905
  type: "http"
794
906
  },
795
907
  EXPECTATION_FAILED: {
796
908
  httpStatus: 417,
797
909
  code: "EXPECTATION_FAILED",
798
- name: "ExpectationFailedError",
799
- message: "Expectation failed",
910
+ name: "Expectation Failed Error",
911
+ message: "expectation failed",
800
912
  uiMessage: "The server cannot meet the requirements of the request.",
801
913
  type: "http"
802
914
  },
803
915
  IM_A_TEAPOT: {
804
916
  httpStatus: 418,
805
917
  code: "IM_A_TEAPOT",
806
- name: "ImATeapotError",
807
- message: "I'm a teapot",
918
+ name: "Im A Teapot Error",
919
+ message: "i'm a teapot",
808
920
  uiMessage: "I'm a teapot and cannot brew coffee.",
809
921
  type: "http"
810
922
  },
811
923
  UNPROCESSABLE_ENTITY: {
812
924
  httpStatus: 422,
813
925
  code: "UNPROCESSABLE_ENTITY",
814
- name: "UnprocessableEntityError",
815
- message: "Unprocessable entity",
926
+ name: "Unprocessable Entity Error",
927
+ message: "unprocessable entity",
816
928
  uiMessage: "The request contains invalid data. Please check your input.",
817
929
  type: "http"
818
930
  },
819
931
  LOCKED: {
820
932
  httpStatus: 423,
821
933
  code: "LOCKED",
822
- name: "LockedError",
823
- message: "Locked",
934
+ name: "Locked Error",
935
+ message: "locked",
824
936
  uiMessage: "This resource is locked and cannot be modified.",
825
937
  type: "http"
826
938
  },
827
939
  FAILED_DEPENDENCY: {
828
940
  httpStatus: 424,
829
941
  code: "FAILED_DEPENDENCY",
830
- name: "FailedDependencyError",
831
- message: "Failed dependency",
942
+ name: "Failed Dependency Error",
943
+ message: "failed dependency",
832
944
  uiMessage: "The request failed due to a dependency error.",
833
945
  type: "http"
834
946
  },
835
947
  TOO_EARLY: {
836
948
  httpStatus: 425,
837
949
  code: "TOO_EARLY",
838
- name: "TooEarlyError",
839
- message: "Too early",
950
+ name: "Too Early Error",
951
+ message: "too early",
840
952
  uiMessage: "The request was sent too early. Please try again later.",
841
953
  type: "http"
842
954
  },
843
955
  UPGRADE_REQUIRED: {
844
956
  httpStatus: 426,
845
957
  code: "UPGRADE_REQUIRED",
846
- name: "UpgradeRequiredError",
847
- message: "Upgrade required",
958
+ name: "Upgrade Required Error",
959
+ message: "upgrade required",
848
960
  uiMessage: "Please upgrade to continue using this service.",
849
961
  type: "http"
850
962
  },
851
963
  PRECONDITION_REQUIRED: {
852
964
  httpStatus: 428,
853
965
  code: "PRECONDITION_REQUIRED",
854
- name: "PreconditionRequiredError",
855
- message: "Precondition required",
966
+ name: "Precondition Required Error",
967
+ message: "precondition required",
856
968
  uiMessage: "Required conditions are missing from the request.",
857
969
  type: "http"
858
970
  },
859
971
  TOO_MANY_REQUESTS: {
860
972
  httpStatus: 429,
861
973
  code: "TOO_MANY_REQUESTS",
862
- name: "TooManyRequestsError",
863
- message: "Too many requests",
974
+ name: "Too Many Requests Error",
975
+ message: "too many requests",
864
976
  uiMessage: "You have made too many requests. Please wait and try again.",
865
977
  type: "http"
866
978
  },
867
979
  REQUEST_HEADER_FIELDS_TOO_LARGE: {
868
980
  httpStatus: 431,
869
981
  code: "REQUEST_HEADER_FIELDS_TOO_LARGE",
870
- name: "RequestHeaderFieldsTooLargeError",
871
- message: "Request header fields too large",
982
+ name: "Request Header Fields Too Large Error",
983
+ message: "request header fields too large",
872
984
  uiMessage: "The request headers are too large.",
873
985
  type: "http"
874
986
  },
875
987
  UNAVAILABLE_FOR_LEGAL_REASONS: {
876
988
  httpStatus: 451,
877
989
  code: "UNAVAILABLE_FOR_LEGAL_REASONS",
878
- name: "UnavailableForLegalReasonsError",
879
- message: "Unavailable for legal reasons",
990
+ name: "Unavailable For Legal Reasons Error",
991
+ message: "unavailable for legal reasons",
880
992
  uiMessage: "This content is unavailable for legal reasons.",
881
993
  type: "http"
882
994
  },
@@ -884,47 +996,47 @@ var PRESETS = {
884
996
  INTERNAL_SERVER_ERROR: {
885
997
  httpStatus: 500,
886
998
  code: "INTERNAL_SERVER_ERROR",
887
- name: "InternalServerError",
888
- message: "Internal server error",
999
+ name: "Internal Server Error",
1000
+ message: "internal server error",
889
1001
  uiMessage: "An unexpected error occurred. Please try again later.",
890
1002
  type: "http"
891
1003
  },
892
1004
  NOT_IMPLEMENTED: {
893
1005
  httpStatus: 501,
894
1006
  code: "NOT_IMPLEMENTED",
895
- name: "NotImplementedError",
896
- message: "Not implemented",
1007
+ name: "Not Implemented Error",
1008
+ message: "not implemented",
897
1009
  uiMessage: "This feature is not yet available.",
898
1010
  type: "http"
899
1011
  },
900
1012
  BAD_GATEWAY: {
901
1013
  httpStatus: 502,
902
1014
  code: "BAD_GATEWAY",
903
- name: "BadGatewayError",
904
- message: "Bad gateway",
1015
+ name: "Bad Gateway Error",
1016
+ message: "bad gateway",
905
1017
  uiMessage: "Unable to connect to the server. Please try again later.",
906
1018
  type: "http"
907
1019
  },
908
1020
  SERVICE_UNAVAILABLE: {
909
1021
  httpStatus: 503,
910
1022
  code: "SERVICE_UNAVAILABLE",
911
- name: "ServiceUnavailableError",
912
- message: "Service unavailable",
1023
+ name: "Service Unavailable Error",
1024
+ message: "service unavailable",
913
1025
  uiMessage: "The service is temporarily unavailable. Please try again later.",
914
1026
  type: "http"
915
1027
  },
916
1028
  GATEWAY_TIMEOUT: {
917
1029
  httpStatus: 504,
918
1030
  code: "GATEWAY_TIMEOUT",
919
- name: "GatewayTimeoutError",
920
- message: "Gateway timeout",
1031
+ name: "Gateway Timeout Error",
1032
+ message: "gateway timeout",
921
1033
  uiMessage: "The server took too long to respond. Please try again.",
922
1034
  type: "http"
923
1035
  },
924
1036
  HTTP_VERSION_NOT_SUPPORTED: {
925
1037
  httpStatus: 505,
926
1038
  code: "HTTP_VERSION_NOT_SUPPORTED",
927
- name: "HTTPVersionNotSupportedError",
1039
+ name: "HTTP Version Not Supported Error",
928
1040
  message: "HTTP version not supported",
929
1041
  uiMessage: "Your browser version is not supported.",
930
1042
  type: "http"
@@ -932,46 +1044,46 @@ var PRESETS = {
932
1044
  VARIANT_ALSO_NEGOTIATES: {
933
1045
  httpStatus: 506,
934
1046
  code: "VARIANT_ALSO_NEGOTIATES",
935
- name: "VariantAlsoNegotiatesError",
936
- message: "Variant also negotiates",
1047
+ name: "Variant Also Negotiates Error",
1048
+ message: "variant also negotiates",
937
1049
  uiMessage: "The server has an internal configuration error.",
938
1050
  type: "http"
939
1051
  },
940
1052
  INSUFFICIENT_STORAGE: {
941
1053
  httpStatus: 507,
942
1054
  code: "INSUFFICIENT_STORAGE",
943
- name: "InsufficientStorageError",
944
- message: "Insufficient storage",
1055
+ name: "Insufficient Storage Error",
1056
+ message: "insufficient storage",
945
1057
  uiMessage: "The server has insufficient storage to complete the request.",
946
1058
  type: "http"
947
1059
  },
948
1060
  LOOP_DETECTED: {
949
1061
  httpStatus: 508,
950
1062
  code: "LOOP_DETECTED",
951
- name: "LoopDetectedError",
952
- message: "Loop detected",
1063
+ name: "Loop Detected Error",
1064
+ message: "loop detected",
953
1065
  uiMessage: "The server detected an infinite loop.",
954
1066
  type: "http"
955
1067
  },
956
1068
  NOT_EXTENDED: {
957
1069
  httpStatus: 510,
958
1070
  code: "NOT_EXTENDED",
959
- name: "NotExtendedError",
960
- message: "Not extended",
1071
+ name: "Not Extended Error",
1072
+ message: "not extended",
961
1073
  uiMessage: "Additional extensions are required.",
962
1074
  type: "http"
963
1075
  },
964
1076
  NETWORK_AUTHENTICATION_REQUIRED: {
965
1077
  httpStatus: 511,
966
1078
  code: "NETWORK_AUTHENTICATION_REQUIRED",
967
- name: "NetworkAuthenticationRequiredError",
968
- message: "Network authentication required",
1079
+ name: "Network Authentication Required Error",
1080
+ message: "network authentication required",
969
1081
  uiMessage: "Network authentication is required to access this resource.",
970
1082
  type: "http"
971
1083
  }
972
- }
1084
+ };
973
1085
  };
974
1086
 
975
- export { ErrorX, HandlingTargets, PRESETS };
1087
+ export { ErrorX, HandlingTargets };
976
1088
  //# sourceMappingURL=index.js.map
977
1089
  //# sourceMappingURL=index.js.map