2 분 소요


  • When developing with SpringBoot, there are situations where Exception handling becomes necessary. I want to document how to handle exceptions in such cases and what methods are available.

Handling Exceptions

  • Let’s work by adding Exceptions to the controller one by one

Creating Basic Controller and Return Object

  • Let’s create a basic controller and an object to hold in the controller’s Response
  • The controller and object were created as follows

    // Controller class
    package com.example.springcontrolleradvice.controller;
    
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequestMapping("/orders")
    public class OrderController {
    
        @GetMapping("/{orderId}")
        public ResponseEntity<CommonResponse> getOrder(@PathVariable String orderId) {
            return ResponseEntity.ok(new CommonResponse("success", "order found", orderId));
        }
    }
    
    
    • When sending a GET request to /orders/{orderId}, it returns the orderId in the Response
    // Controller's Response object
    package com.example.springcontrolleradvice.controller;
    
    public record CommonResponse(
    String Status,
    String message,
    Object data
    ) {}
    

Adding Exception

  • Let’s throw an Exception in the controller when orderId is not 100

    package com.example.springcontrolleradvice.controller;
    
    
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.*;
    
    @RestController
    @RequestMapping("/orders")
    public class OrderController {
    
        @GetMapping("/{orderId}")
        public ResponseEntity<CommonResponse> getOrder(@PathVariable String orderId) throws Exception {
            if(!orderId.equals("100")){
                throw new Exception("order not found");
            }
            return ResponseEntity.ok(new CommonResponse("success", "order found", orderId));
        }
    
    }
    
    
    • When Exception is applied as above, the Exception appears in the log when orderID is not 100

Creating Custom Exception

  • Let’s create a CustomException by inheriting from the occurring Exception

    package com.example.springcontrolleradvice.controller.exception;
    
    public class CustomException extends RuntimeException {
        private String message;
        private String errorCode;
        private String hint;
    
        protected CustomException() {
        }
    
        public CustomException(String message, String errorCode, String hint) {
            this.message = message;
            this.errorCode = errorCode;
            this.hint = hint;
        }
    
        // getters and setters
    }
    
    

Applying CustomException to Controller

package com.example.springcontrolleradvice.controller;

import com.example.springcontrolleradvice.controller.exception.CustomException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
RequestMapping("/orders")

public class OrderController {

    @GetMapping("/{orderId}")
    public ResponseEntity<CommonResponse> getOrder(@PathVariable String orderId) {
        if (!orderId.equals("100")) {
            throw new CustomException("order not found", "ERROR400", "please check the order id");
        }
        return ResponseEntity.ok(new CommonResponse("success", "order found", orderId));
    }

}
  • When CustomException is applied, CustomException is thrown when an Exception occurs

Creating Handler for CustomException

  • The process above only throws an Exception when an Exception occurs. The CustomException message we want is not returned.
  • Let’s include our CustomException in the returned message when throwing an Exception
  • Let’s create a place to intercept Exceptions and return our CustomException
  • Let’s write CustomExceptionInterceptor

    package com.example.springcontrolleradvice.controller.exception;
    
    
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.ControllerAdvice;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
    
    @ControllerAdvice
    public class CustomExceptionInterceptor extends ResponseEntityExceptionHandler {
    
        @ExceptionHandler(CustomException.class)
        public final ResponseEntity<Object> handleCustomException(CustomException ex) {
            CustomExceptionModel exceptionResponse = new CustomExceptionModel(ex.getMessage(), ex.getErrorCode(), ex.getHint());
            return new ResponseEntity(exceptionResponse, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    • Using @ControllerAdvice, we create a place to intercept Exceptions
    • Inherit from ResponseEntityExceptionHandler to make CustomExceptionInterceptor intercept when Exceptions occur
    • CustomExceptionModel is written as a message object with the same structure as CustomException

      package com.example.springcontrolleradvice.controller.exception;
      
      public record CustomExceptionModel(
              String message,
              String errorCode,
              String hint
      ) {
      }
      
      • Returns the exception with the message we wrote

댓글남기기