From 69e163e2e27387c09e1a94c563f9b65435f79d8e Mon Sep 17 00:00:00 2001 From: Faiz Akram <156657523+faizorg@users.noreply.github.com> Date: Sat, 1 Feb 2025 20:16:38 +0530 Subject: [PATCH] Maven updated --- .../java/com/app/dto/StandardResponse.java | 15 ++++ .../app/exception/CustomRuntimeException.java | 26 +++++++ .../app/exception/RestExceptionHandler.java | 73 +++++++++++++++++++ .../java/com/app/utils/MessageConstant.java | 19 +++++ src/main/java/com/app/utils/ResponseUtil.java | 59 +++++++++++++++ src/main/resources/application-local.yml | 8 ++ src/main/resources/error_messages.properties | 42 +++++++++++ .../resources/error_messages_hi.properties | 15 ++++ .../resources/success_messages.properties | 2 + .../resources/success_messages_hi.properties | 15 ++++ 10 files changed, 274 insertions(+) create mode 100644 src/main/java/com/app/dto/StandardResponse.java create mode 100644 src/main/java/com/app/exception/CustomRuntimeException.java create mode 100644 src/main/java/com/app/exception/RestExceptionHandler.java create mode 100644 src/main/java/com/app/utils/MessageConstant.java create mode 100644 src/main/java/com/app/utils/ResponseUtil.java create mode 100644 src/main/resources/error_messages.properties create mode 100644 src/main/resources/error_messages_hi.properties create mode 100644 src/main/resources/success_messages.properties create mode 100644 src/main/resources/success_messages_hi.properties diff --git a/src/main/java/com/app/dto/StandardResponse.java b/src/main/java/com/app/dto/StandardResponse.java new file mode 100644 index 0000000..b48984d --- /dev/null +++ b/src/main/java/com/app/dto/StandardResponse.java @@ -0,0 +1,15 @@ +package com.app.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class StandardResponse { + private String responseCode; // The response code (e.g., "E1005") + private String responseDescription; // The response description (e.g., "Invalid method argument.") + private T response; // Generic type to hold any object (e.g., data or error details) + private boolean isOkay; // Indicates success (true) or failure (false) +} \ No newline at end of file diff --git a/src/main/java/com/app/exception/CustomRuntimeException.java b/src/main/java/com/app/exception/CustomRuntimeException.java new file mode 100644 index 0000000..8c71528 --- /dev/null +++ b/src/main/java/com/app/exception/CustomRuntimeException.java @@ -0,0 +1,26 @@ +package com.app.exception; + +import lombok.Getter; +import org.springframework.http.HttpStatus; + +@Getter +public class CustomRuntimeException extends RuntimeException { + + private final String responseCode; // Unique error code + private final HttpStatus httpStatus; // HTTP status associated with the exception + private final Object[] args; + + /** + * Constructor for CustomRuntimeException. + * + * @param responseCode The unique error code. + * @param httpStatus The HTTP status associated with the exception. + * @param args Arguments for dynamic message formatting. + */ + public CustomRuntimeException(String responseCode, HttpStatus httpStatus, Object... args) { + super(responseCode); // Use responseCode as the default message for the exception + this.responseCode = responseCode; + this.httpStatus = httpStatus; + this.args = args; + } +} diff --git a/src/main/java/com/app/exception/RestExceptionHandler.java b/src/main/java/com/app/exception/RestExceptionHandler.java new file mode 100644 index 0000000..9e64da7 --- /dev/null +++ b/src/main/java/com/app/exception/RestExceptionHandler.java @@ -0,0 +1,73 @@ +package com.app.exception; + +import com.app.dto.StandardResponse; +import com.app.utils.MessageConstant; +import com.app.utils.ResponseUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +import java.util.stream.Collectors; + +@RestControllerAdvice +@RequiredArgsConstructor +@Log4j2 +public class RestExceptionHandler { + + private final ResponseUtil responseUtil; + + /** + * Handles validation errors for method arguments. + * + * @param ex The MethodArgumentNotValidException to handle. + * @return A ResponseEntity with a structured error response. + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) { + return buildErrorResponse(MessageConstant.E1005, HttpStatus.BAD_REQUEST, ex.getBindingResult().getFieldErrors().stream() + .collect(Collectors.toMap(FieldError::getField, responseUtil::getMessage))); + } + + /** + * Handles custom ServiceException. + * + * @param ex The ServiceException to handle. + * @return A ResponseEntity with an error response. + */ + @ExceptionHandler(CustomRuntimeException.class) + public ResponseEntity> handleServiceException(CustomRuntimeException ex) { + log.error("Service exception: ", ex); + return buildErrorResponse(ex.getResponseCode(), ex.getHttpStatus(), ex.getArgs()); + } + + /** + * Handles generic RuntimeExceptions. + * + * @param ex The RuntimeException to handle. + * @return A ResponseEntity with an error response. + */ + @ExceptionHandler(RuntimeException.class) + public ResponseEntity> handleRuntimeException(RuntimeException ex) { + log.error("Runtime exception: ", ex); + return buildErrorResponse(MessageConstant.E1000, HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage()); + } + + + /** + * Utility method to build a standardized error response. + * + * @param responseCode The response code for the error. + * @param details The error details to include in the response. + * @param httpStatus The HTTP status for the response. + * @return A ResponseEntity containing the StandardResponse. + */ + private ResponseEntity> buildErrorResponse(String responseCode, HttpStatus httpStatus, Object... details) { + StandardResponse response = responseUtil.createErrorResponse(responseCode, details); + return ResponseEntity.status(httpStatus).body(response); + } +} diff --git a/src/main/java/com/app/utils/MessageConstant.java b/src/main/java/com/app/utils/MessageConstant.java new file mode 100644 index 0000000..c4517df --- /dev/null +++ b/src/main/java/com/app/utils/MessageConstant.java @@ -0,0 +1,19 @@ +package com.app.utils; + +public class MessageConstant { + private MessageConstant() { + } + //Success + public static final String S0001 = "s0001"; + // Error Message Constant + public static final String E1000 = "e1000"; + public static final String E1001 = "e1001"; + public static final String E1002 = "e1002"; + public static final String E1003 = "e1003"; + public static final String E1004 = "e1004"; + public static final String E1005 = "e1005"; + public static final String E1006 = "e1006"; + public static final String E1007 = "e1007"; + + +} diff --git a/src/main/java/com/app/utils/ResponseUtil.java b/src/main/java/com/app/utils/ResponseUtil.java new file mode 100644 index 0000000..653bfbe --- /dev/null +++ b/src/main/java/com/app/utils/ResponseUtil.java @@ -0,0 +1,59 @@ +package com.app.utils; + +import com.app.dto.StandardResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.context.MessageSource; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +@Component +@RequiredArgsConstructor +public class ResponseUtil { + + private final MessageSource messageSource; + + + /** + * Creates a success response. + * + * @param responseCode The response code for success. + * @param responseObject The object to include in the response. + * @return A StandardResponse object. + */ + public StandardResponse createSuccessResponse(String responseCode, T responseObject, Object... args) { + return new StandardResponse<>(StringUtils.uncapitalizeAsProperty(responseCode), getMessage("success.description." + responseCode, args), responseObject, true); + } + + /** + * Creates an error response. + * + * @param responseCode The response code for the error. + * @param errorDetails Optional error details to include in the response. + * @return A StandardResponse object. + */ + public StandardResponse createErrorResponse(String responseCode, T errorDetails, Object... args) { + return new StandardResponse<>(StringUtils.uncapitalizeAsProperty(responseCode), getMessage("error.description." + responseCode, args), errorDetails, false); + } + + /** + * Retrieves a message from the MessageSource based on the current locale. + * + * @param key The message key. + * @return The localized message. + */ + public String getMessage(String key, Object... args) { + return messageSource.getMessage(key, args, LocaleContextHolder.getLocale()); + } + + /** + * Retrieves a message from the MessageSource based on the current locale. + * + * @return The localized message. + */ + public String getMessage(MessageSourceResolvable resolvable) { + return messageSource.getMessage(resolvable, LocaleContextHolder.getLocale()); + } + +} diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml index d2f8b2d..2bbeceb 100644 --- a/src/main/resources/application-local.yml +++ b/src/main/resources/application-local.yml @@ -2,3 +2,11 @@ app: logs: path: C:/${spring.application.name}/logs +####################### START READ PROPERTIES FILE ####################### +spring: + messages: + basename: error_messages,success_messages # Or provide full paths if needed + cache-duration: 3600 + encoding: UTF-8 + web: + locale: en \ No newline at end of file diff --git a/src/main/resources/error_messages.properties b/src/main/resources/error_messages.properties new file mode 100644 index 0000000..586fe0e --- /dev/null +++ b/src/main/resources/error_messages.properties @@ -0,0 +1,42 @@ +# Error Code Properties +error.code.e1000=E1000 +error.description.e1000=Something went wrong! {0} + +error.code.e1001=E1001 +error.description.e1001=Authorization header cannot be blank or invalid. + +error.code.e1002=E1002 +error.description.e1002=Unable to extract email ID from the token. Please generate a new token. + +error.code.e1003=E1003 +error.description.e1003=Invalid token. Please generate a new token. + +error.code.e1004=E1004 +error.description.e1004=Authentication token is required. + +error.code.e1005=E1005 +error.description.e1005=Invalid method argument. + +error.code.e1006=E1006 +error.description.e1006=No matching enum found. + +error.code.e1007=E1007 +error.description.e1007=Duplicate entry detected. + + + +# fullName validations +fullName.not.blank=Full name cannot be blank +fullName.size=Full name must not exceed 100 characters +# email validations +email.not.blank=Email cannot be blank +email.invalid=Please provide a valid email address +# password validations +password.not.blank=Password cannot be blank +password.pattern=Password must be at least 8 characters, include an alphanumeric character, and one special character +# authProvider validations +authProvider.notnull=Auth provider is required +authProvider.invalid=Auth provider must be one of the values: 4, 5, 6 +# roleId validations +roleId.notnull=Role ID is required +roleId.invalid=Role ID must be either 2 or 3 diff --git a/src/main/resources/error_messages_hi.properties b/src/main/resources/error_messages_hi.properties new file mode 100644 index 0000000..2bc7df5 --- /dev/null +++ b/src/main/resources/error_messages_hi.properties @@ -0,0 +1,15 @@ +# fullName validations +fullName.no.tblank=???? ??? ???? ???? ?? ???? +fullName.size=???? ??? 100 ??????? ?? ???? ???? ???? ????? +# email validations +email.not.blank=???? ???? ???? ?? ???? +email.invalid=????? ?? ????? ???? ??? ?????? ???? +# password validations +password.not.blank=??????? ???? ???? ?? ???? +password.pattern=??????? ?? ?? ?? 8 ??????? ?? ???? ?????, ?? ??????????????? ?? ?? ????? ????? ????? ???? ????? +# authProvider validations +authProvider.notnull=?? ????????? ?????? ?? +authProvider.invalid=?? ????????? ?? ??? 3, 4, 5 ??? ?? ?? ???? ????? +# roleId validations +roleId.notnull=?????? ???? ?????? ?? +roleId.invalid=?????? ???? 2 ?? 3 ??? ?? ?? ???? ????? diff --git a/src/main/resources/success_messages.properties b/src/main/resources/success_messages.properties new file mode 100644 index 0000000..aab07d5 --- /dev/null +++ b/src/main/resources/success_messages.properties @@ -0,0 +1,2 @@ +success.description.s0001=Request processed successfully. +success.description.s0002=Token generated successfully. diff --git a/src/main/resources/success_messages_hi.properties b/src/main/resources/success_messages_hi.properties new file mode 100644 index 0000000..256cfb5 --- /dev/null +++ b/src/main/resources/success_messages_hi.properties @@ -0,0 +1,15 @@ +# fullName validations +fullName.no.tblank=???? ??? ???? ???? ?? ???? +fullName.size=???? ??? 100 ??????? ?? ???? ???? ???? ????? +# email validations +email.not.blank=???? ???? ???? ?? ???? +email.invalid=????? ?? ????? ???? ??? ?????? ???? +# password validations +password.not.blank=??????? ???? ???? ?? ???? +password.pattern=??????? ?? ?? ?? 8 ??????? ?? ???? ?????, ?? ??????????????? ?? ?? ????? ????? ????? ???? ????? +# authProvider validations +authProvider.notnull=?? ????????? ?????? ?? +authProvider.invalid=?? ????????? ?? ??? 3, 4, 5 ??? ?? ?? ???? ????? +# roleId validations +roleId.notnull=?????? ???? ?????? ?? +roleId.invalid=?????? ???? 2 ?? 3 ??? ?? ?? ???? ????? \ No newline at end of file