mark whalf
mark whalf

Reputation: 45

How to give specific error instead of 500 internal

I have wrote specific exception, but my GlobalExceptionHandler does not work, any help would be appreciated. Thank you.

my GlobalException class below;

@ControllerAdvice
public class GlobalExceptionHandler {

    public static final String EXCEPTION_OCCURED_LOG_PREFIX = "Exception occured: {}";
    public static final String EXCEPTION_OCCURED_LOG_DETAIL = "Exception log detail occured: {}, class: {}";
    Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ExceptionHandler({BadRequestException.class})
    public ResponseEntity<BaseResponse> handleBadRequest(BadRequestException ex) {


        String logSuffix = Arrays.toString(ex.getStackTrace());
        logger.error(EXCEPTION_OCCURED_LOG_PREFIX, logSuffix);
        logger.error(EXCEPTION_OCCURED_LOG_DETAIL, ex.getMessage(), ex.getClass());

        BaseResponse response = new BaseResponse();
        response.setCode(Constants.B_BADREQUEST);
        response.setMessage("BadRequestException occured! Exception details: ".concat(ex.getMessage()));

        return ResponseEntity
                .status(HttpStatus.BAD_REQUEST)
                .body(response);
    }

my BaseResponse class below;

public class BaseResponse {

    private String code;

    private String message;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

my Request Model class below;

@Entity
@Data
public class SchoolRequest {
        @Id
        @NotNull
        @JsonProperty("school")
        private String school;

calling Exception class below;

  private void schoolRule(SchoolRequest schoolRequest) {
    
            if (schoolRequest.getSchool() == null || schoolRequest.getSchool().isEmpty()) {
                throw new BadRequestException("School can not be null or empty");
            }
        }

my BadRequestException Class below;

public class BadRequestException  extends RuntimeException{

    public BadRequestException(String message) {
        super(message);
    }

}

my Controller class below;

public class SchoolController {

    private final School schoolService;

    @PostMapping(ApiPaths.schoolController.CTRL)
    public ResponseEntity<SchoolResponse> createSchool(@Valid @RequestBody SchoolRequest request) throws Exception {

        return schoolService.createSchool(request);
    }
}

Error code I am receiving below;

"code": "INTERNAL_SERVER_ERROR",
    "message": "Internal Server Error occured! Exception details: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<eu.demo.school.model.SchoolResponse> eu.demo.school.controller.SchoolController.createSchool java.lang.Exception: [Field error in object 'schoolRequest' on field 'school': rejected value [null]; codes [NotNull.schoolRequest.prefix,NotNull.prefix,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [schoolRequest.prefix,prefix]; arguments []; default message [school]]; default message [must not be null]]

Upvotes: 0

Views: 227

Answers (1)

dbrewster
dbrewster

Reputation: 693

Your ExceptionHandler does not catch all exceptions. As of right now, it only catches all BadRequestExceptions while the exception you are getting is an INTERNAL_SERVER_ERROR. The problem is that a different exception is being thrown before you reach your schoolRule() method.

So the question is where the exception is being thrown. While I can't say for certain without seeing what's happening inside schoolService.createSchool(request); and how schoolRule(request) is being called, my guess is that it is being caught by your @NotNull and @Valid annotations.

The "Validation failed for argument [0] in public" is the same as the default error message that is provided by @Valid so I am guessing you have other code that wraps the default MethodArgumentNotValidException with your custom INTERNAL_SERVER_ERROR.

If I am correct, you will probably want to add the INTERNAL_SERVER_ERROR to your ControllerAdvice class although you could also just call your schoolRule() method before you call your javax validator

Upvotes: 1

Related Questions