reslib 2.0.0 → 2.0.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.
@@ -1,3 +1,4 @@
1
+ import { ValidatorBulkError, ValidatorClassError, ValidatorError } from '../validator/errors';
1
2
  /**
2
3
  * Hook function type for intercepting exceptions (e.g., for logging).
3
4
  */
@@ -68,6 +69,10 @@ export declare class BaseException<TDetails = unknown, TCause = unknown> extends
68
69
  */
69
70
  readonly timestamp: Date;
70
71
  readonly success: boolean;
72
+ /**
73
+ * The validation error that caused this exception.
74
+ */
75
+ validatorError?: ValidatorError | ValidatorClassError | ValidatorBulkError;
71
76
  /**
72
77
  * Creates a new BaseException instance.
73
78
  *
@@ -808,6 +813,331 @@ export declare class BaseException<TDetails = unknown, TCause = unknown> extends
808
813
  * @see {@link parseErrorDetails} - Override for custom detail extraction only
809
814
  */
810
815
  protected static createFromError<TDetails = unknown, TException extends BaseException<TDetails> = BaseException<TDetails>, TCause = unknown>(this: BaseExceptionConstructor<TDetails, TException>, error: unknown, options?: BaseExceptionOptions<TDetails, TCause>): TException;
816
+ /**
817
+ * Type guard to check if an error is a ValidatorClassError.
818
+ *
819
+ * ValidatorClassError represents validation failures for class/object validation,
820
+ * containing field-level errors with detailed information about which properties
821
+ * failed validation and why.
822
+ *
823
+ * @param error - The value to check
824
+ * @returns True if the error is a ValidatorClassError, false otherwise
825
+ *
826
+ * @example
827
+ * ```typescript
828
+ * try {
829
+ * await validateUserInput(data);
830
+ * } catch (error) {
831
+ * if (BaseException.isValidatorClassError(error)) {
832
+ * // TypeScript now knows error is ValidatorClassError
833
+ * console.log('Field errors:', error.fieldErrors);
834
+ * error.fieldErrors.forEach(fieldError => {
835
+ * console.log(`${fieldError.field}: ${fieldError.message}`);
836
+ * });
837
+ * }
838
+ * }
839
+ * ```
840
+ *
841
+ * @see {@link ValidatorClassError} - The class validation error type
842
+ * @see {@link isValidatorError} - Check for any validator error type
843
+ * @see {@link getValidationError} - Extract validation error from exceptions
844
+ */
845
+ static isValidatorClassError(error: unknown): error is ValidatorClassError;
846
+ /**
847
+ * Type guard to check if an error is a ValidatorBulkError.
848
+ *
849
+ * ValidatorBulkError represents validation failures for bulk/array validation,
850
+ * containing errors for multiple items in an array with index information.
851
+ *
852
+ * @param error - The value to check
853
+ * @returns True if the error is a ValidatorBulkError, false otherwise
854
+ *
855
+ * @example
856
+ * ```typescript
857
+ * try {
858
+ * await validateBulkUsers(userArray);
859
+ * } catch (error) {
860
+ * if (BaseException.isValidatorBulkError(error)) {
861
+ * // TypeScript now knows error is ValidatorBulkError
862
+ * console.log(`${error.itemCount} items failed validation`);
863
+ * error.itemErrors.forEach(itemError => {
864
+ * console.log(`Item[${itemError.index}]: ${itemError.message}`);
865
+ * });
866
+ * }
867
+ * }
868
+ * ```
869
+ *
870
+ * @see {@link ValidatorBulkError} - The bulk validation error type
871
+ * @see {@link isValidatorError} - Check for any validator error type
872
+ * @see {@link getValidationError} - Extract validation error from exceptions
873
+ */
874
+ static isValidatorBulkError(error: unknown): error is ValidatorBulkError;
875
+ /**
876
+ * Type guard to check if an error is a ValidatorError (single field/value validation).
877
+ *
878
+ * ValidatorError represents validation failures for individual field/value validation,
879
+ * containing information about a single validation rule failure.
880
+ *
881
+ * @param error - The value to check
882
+ * @returns True if the error is a ValidatorError, false otherwise
883
+ *
884
+ * @example
885
+ * ```typescript
886
+ * try {
887
+ * await validateEmail(email);
888
+ * } catch (error) {
889
+ * if (BaseException.isValidatorError(error)) {
890
+ * // TypeScript now knows error is ValidatorError
891
+ * console.log('Validation failed:', error.message);
892
+ * console.log('Field:', error.field);
893
+ * console.log('Rule:', error.rule);
894
+ * }
895
+ * }
896
+ * ```
897
+ *
898
+ * @see {@link ValidatorError} - The single field validation error type
899
+ * @see {@link isValidatorClassError} - Check for class validation errors
900
+ * @see {@link isValidatorBulkError} - Check for bulk validation errors
901
+ * @see {@link getValidationError} - Extract validation error from exceptions
902
+ */
903
+ static isValidatorError(error: unknown): error is ValidatorError;
904
+ /**
905
+ * Type guard to check if an error is any type of validator error.
906
+ *
907
+ * This is a convenience method that checks if the error is a `ValidatorError`,
908
+ * `ValidatorClassError`, or `ValidatorBulkError`. Use this when you want to
909
+ * handle any validation error generically without caring about the specific type.
910
+ *
911
+ * **Note**: This method is an alias for `Validator.isAnyError()`.
912
+ * Both methods provide identical functionality and can be used interchangeably.
913
+ *
914
+ * **When to use this vs specific type guards:**
915
+ * - Use `isAnyValidatorError()` when you want to handle ALL validator errors the same way
916
+ * - Use `isValidatorError()`, `isValidatorClassError()`, or `isValidatorBulkError()`
917
+ * when you need type-specific handling
918
+ *
919
+ * @param error - The value to check
920
+ * @returns True if the error is any type of validator error, false otherwise
921
+ *
922
+ * @example
923
+ * ```typescript
924
+ * // Generic validation error handling
925
+ * try {
926
+ * await processData(data);
927
+ * } catch (error) {
928
+ * if (BaseException.isAnyValidatorError(error)) {
929
+ * // Handle any validation error
930
+ * console.log('Validation failed:', error.message);
931
+ * return { success: false, type: 'validation', error };
932
+ * }
933
+ * // Handle other error types
934
+ * console.error('Unexpected error:', error);
935
+ * return { success: false, type: 'unknown', error };
936
+ * }
937
+ * ```
938
+ *
939
+ * @example
940
+ * ```typescript
941
+ * // Check before extracting validation details
942
+ * function handleError(error: unknown) {
943
+ * if (BaseException.isAnyValidatorError(error)) {
944
+ * // Now we know it's a validator error, extract it
945
+ * const validationError = BaseException.getValidationError(error);
946
+ *
947
+ * // Then check specific type if needed
948
+ * if (BaseException.isValidatorClassError(validationError)) {
949
+ * return formatFieldErrors(validationError.fieldErrors);
950
+ * } else if (BaseException.isValidatorBulkError(validationError)) {
951
+ * return formatBulkErrors(validationError.itemErrors);
952
+ * }
953
+ * }
954
+ *
955
+ * return formatGenericError(error);
956
+ * }
957
+ * ```
958
+ *
959
+ * @example
960
+ * ```typescript
961
+ * // API error response handling
962
+ * async function apiCall(endpoint: string, data: any) {
963
+ * try {
964
+ * const response = await fetch(endpoint, {
965
+ * method: 'POST',
966
+ * body: JSON.stringify(data)
967
+ * });
968
+ * const result = await response.json();
969
+ *
970
+ * if (!response.ok) {
971
+ * // Check if it's a validation error
972
+ * if (BaseException.isAnyValidatorError(result)) {
973
+ * throw AppException.from(result, {
974
+ * code: 'VALIDATION_ERROR',
975
+ * statusCode: 400
976
+ * });
977
+ * }
978
+ * throw AppException.from(result);
979
+ * }
980
+ *
981
+ * return result;
982
+ * } catch (error) {
983
+ * if (BaseException.isAnyValidatorError(error)) {
984
+ * // Special handling for validation errors
985
+ * notifyUser('Please check your input');
986
+ * }
987
+ * throw error;
988
+ * }
989
+ * }
990
+ * ```
991
+ *
992
+ * @example
993
+ * ```typescript
994
+ * // Logging with error type detection
995
+ * function logError(error: unknown) {
996
+ * const errorType = BaseException.isAnyValidatorError(error)
997
+ * ? 'VALIDATION'
998
+ * : BaseException.is(error)
999
+ * ? 'APPLICATION'
1000
+ * : 'UNKNOWN';
1001
+ *
1002
+ * logger.error({
1003
+ * type: errorType,
1004
+ * message: error instanceof Error ? error.message : String(error),
1005
+ * details: BaseException.isAnyValidatorError(error) ? error : undefined
1006
+ * });
1007
+ * }
1008
+ * ```
1009
+ *
1010
+ * @remarks
1011
+ * **Behavior**:
1012
+ * - Returns `true` if error is `ValidatorError`, `ValidatorClassError`, or `ValidatorBulkError`
1013
+ * - Returns `false` for all other error types
1014
+ * - Does NOT check wrapped exceptions (use `getValidationError()` for that)
1015
+ *
1016
+ * **Type Safety**:
1017
+ * - TypeScript will narrow the type to the union of all validator error types
1018
+ * - Use specific type guards for further narrowing if needed
1019
+ *
1020
+ * **Performance**:
1021
+ * - Performs up to 3 type checks (short-circuits on first match)
1022
+ * - Very fast for most cases due to short-circuiting
1023
+ *
1024
+ * **Alias Information**:
1025
+ * - This method delegates to `Validator.isAnyError()`
1026
+ * - Use whichever is more convenient in your context
1027
+ * - Both provide identical type narrowing and behavior
1028
+ *
1029
+ * @see {@link isValidatorError} - Check for single field validation errors only
1030
+ * @see {@link isValidatorClassError} - Check for class validation errors only
1031
+ * @see {@link isValidatorBulkError} - Check for bulk validation errors only
1032
+ * @see {@link getValidationError} - Extract validation error from exceptions (checks wrapped errors)
1033
+ * @see {@link Validator.isAnyError} - Original implementation in Validator class
1034
+ * @see {@link ValidatorError} - Single field validation error type
1035
+ * @see {@link ValidatorClassError} - Class validation error type
1036
+ * @see {@link ValidatorBulkError} - Bulk validation error type
1037
+ */
1038
+ static isAnyValidatorError(error: unknown): error is ValidatorError | ValidatorClassError | ValidatorBulkError;
1039
+ /**
1040
+ * Extracts the underlying validation error from an error or exception.
1041
+ *
1042
+ * This method checks if the provided error is a validation error directly,
1043
+ * or if it's a BaseException that wraps a validation error. It returns the
1044
+ * validation error if found, or null otherwise.
1045
+ *
1046
+ * **Use Cases**:
1047
+ * - Extract validation errors from caught exceptions
1048
+ * - Check if an API error response contains validation failures
1049
+ * - Access detailed field-level validation errors for custom error handling
1050
+ *
1051
+ * @param error - The error to extract validation error from
1052
+ * @returns The validation error if found, null otherwise
1053
+ *
1054
+ * @example
1055
+ * ```typescript
1056
+ * // Extract from API exception
1057
+ * try {
1058
+ * await api.createUser(userData);
1059
+ * } catch (error) {
1060
+ * const validationError = BaseException.getValidationError(error);
1061
+ * if (validationError) {
1062
+ * // Handle validation error specifically
1063
+ * if (BaseException.isValidatorClassError(validationError)) {
1064
+ * // Show field-level errors to user
1065
+ * validationError.fieldErrors.forEach(fieldError => {
1066
+ * showFieldError(fieldError.field, fieldError.message);
1067
+ * });
1068
+ * }
1069
+ * } else {
1070
+ * // Handle other error types
1071
+ * showGenericError(error);
1072
+ * }
1073
+ * }
1074
+ * ```
1075
+ *
1076
+ * @example
1077
+ * ```typescript
1078
+ * // Check validation error in action handler
1079
+ * async function handleFormSubmit(formData: FormData) {
1080
+ * try {
1081
+ * return await submitForm(formData);
1082
+ * } catch (error) {
1083
+ * const validationError = AppException.getValidationError(error);
1084
+ *
1085
+ * if (validationError && AppException.isValidatorClassError(validationError)) {
1086
+ * // Return field errors to form
1087
+ * return {
1088
+ * success: false,
1089
+ * fieldErrors: validationError.fieldErrors.reduce((acc, err) => {
1090
+ * acc[err.field] = err.message;
1091
+ * return acc;
1092
+ * }, {} as Record<string, string>)
1093
+ * };
1094
+ * }
1095
+ *
1096
+ * // Return generic error
1097
+ * return {
1098
+ * success: false,
1099
+ * message: error.message
1100
+ * };
1101
+ * }
1102
+ * }
1103
+ * ```
1104
+ *
1105
+ * @example
1106
+ * ```typescript
1107
+ * // Bulk validation error handling
1108
+ * try {
1109
+ * await validateBulkImport(records);
1110
+ * } catch (error) {
1111
+ * const validationError = BaseException.getValidationError(error);
1112
+ *
1113
+ * if (validationError && BaseException.isValidatorBulkError(validationError)) {
1114
+ * console.log(`${validationError.itemCount} of ${validationError.totalCount} items failed`);
1115
+ * validationError.itemErrors.forEach(itemError => {
1116
+ * console.log(`Row ${itemError.index + 1}: ${itemError.message}`);
1117
+ * });
1118
+ * }
1119
+ * }
1120
+ * ```
1121
+ *
1122
+ * @remarks
1123
+ * **Behavior**:
1124
+ * - Returns the error directly if it's a validator error
1125
+ * - Extracts `validatorError` property from BaseException instances
1126
+ * - Returns null if no validation error is found
1127
+ * - Works with wrapped exceptions (checks the `validatorError` property)
1128
+ *
1129
+ * **Type Safety**:
1130
+ * - Use with type guard methods for proper TypeScript narrowing
1131
+ * - Combine with `isValidatorClassError()` or `isValidatorBulkError()` for specific handling
1132
+ *
1133
+ * @see {@link isValidatorError} - Check if error is a single field validation error
1134
+ * @see {@link isValidatorClassError} - Check if error is a class validation error
1135
+ * @see {@link isValidatorBulkError} - Check if error is a bulk validation error
1136
+ * @see {@link ValidatorError} - Single field validation error type
1137
+ * @see {@link ValidatorClassError} - Class validation error type
1138
+ * @see {@link ValidatorBulkError} - Bulk validation error type
1139
+ */
1140
+ static getValidationError(error: unknown): ValidatorError | ValidatorClassError | ValidatorBulkError | null;
811
1141
  /**
812
1142
  * Protected method to extract a human-readable message from an error value.
813
1143
  *
@@ -852,12 +1182,6 @@ export declare class BaseException<TDetails = unknown, TCause = unknown> extends
852
1182
  * return super.parseErrorMessage(error, options);
853
1183
  * }
854
1184
  * }
855
- *
856
- * const validationError = {
857
- * errors: [{ field: 'email', message: 'Invalid format' }]
858
- * };
859
- * const ex = ValidationException.from(validationError);
860
- * // ex.message === 'Validation failed for email: Invalid format'
861
1185
  * ```
862
1186
  *
863
1187
  * @example