[스프링] API 예외 처리

홍건의·2024년 6월 6일
0

스프링 학습

목록 보기
3/5

@ExceptionHandler 사용

@Slf4j
@RestController
public class ApiExceptionController {

	
	// 이하 예외 발생 시 처리하고 싶은 내용 작성
    
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(IllegalArgumentException.class)
    public ErrorResult illegalExHandle(IllegalArgumentException e) {
    	log.error(e.getMessage());
        return new ErrorResult(" ", e.getMessage());
    }
    
    @ExceptionHandler
    public ResponseEntity<ErrorResult> userExHandle(UserException e) {
    	log.error(e.getMessage());
        return new ResponseEntity<>(new ErrorResult, HttpStatus.BAD_REQUEST);
    }
    
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler
    public ErrorResult exHandle(Exception e) {
    	log.error(e.getMessage());
        return new ErrorResult("~~");
    }
    
    // 이하 컨트롤러 코드 작성
    @GetMapping("/members/{id}")
    public MemberDto getMember(@PathVariable("id) String id) {
 
 		if("id".equals(id)) {
        	throw new RuntimeException("~~");
        }
        ...        
    }
}

@ExceptionHandler를 선언하고 해당 컨트롤러에서 해당 예외 발생 시 처리하고 싶은 내용을 작성한다.

실행 원리

(1) Exception이 발생하여 컨트롤러 밖으로 던져진다.
(2) 예외가 발생했으므로 ExceptionResolver가 작동한다. 우선순위가 가장 높은 ExceptionHandlerExceptionResolver가 작동한다.
(3) ExceptionHandlerExceptionResolver는 해당 Exception을 처리할 수 있는 @ExceptionHandler가 있는지 확인한다.
(4) 있으면 해당 메소드를 처리한다.
(5) 이후 HTTP 컨버터가 사용되고 맞추어 반환한다.

ExceptionResolver우선순위

  1. ExceptionHandlerExceptionResolver
  2. ResponseStatusExceptionResolver
  3. DefaultHandlerExceptionResolver

@ControllerAdvice 사용

@ControllerAdvice는 예외 처리 코드 부분과 정상 처리 부분을 분리하여 작성할 수 있게 해준다.

@Slf4j
@RestController
public class ApiExceptionController {

	
	// 기존 @ExceptionHandler를 통한 예외처리 부분 제거
    
    // 이하 기존 컨트롤러 코드
    @GetMapping("/members/{id}")
    public MemberDto getMember(@PathVariable("id) String id) {
 
 		if("id".equals(id)) {
        	throw new RuntimeException("~~");
        }
        ...        
    }
}
@Sl4fj
@RestControllerAdvice
public class ExControllerAdvice {

	// 위 컨트롤러 상단에 있던 코드 그대로 이하 작성
	
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(IllegalArgumentException.class)
    public ErrorResult illegalExHandle(IllegalArgumentException e) {
    	log.error(e.getMessage());
        return new ErrorResult(" ", e.getMessage());
    }
    
    @ExceptionHandler
    public ResponseEntity<ErrorResult> userExHandle(UserException e) {
    	log.error(e.getMessage());
        return new ResponseEntity<>(new ErrorResult, HttpStatus.BAD_REQUEST);
    }
    
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler
    public ErrorResult exHandle(Exception e) {
    	log.error(e.getMessage());
        return new ErrorResult("~~");
    }
    
}

@ControllerAdvice는 컨트롤러를 적용 범위를 지정할 수 있다. 적용하지 않으면 전체 컨트롤러를 대상으로 적용한다.
@RestControllerAdvice@ControllerAdvice와 같고, @ResponseBody가 추가되어 있다.

이하 컨트롤러 범위 지정 예시


@ControllerAdvice(annotations = RestController.class)
public class ExampleAdvice1 {}

@ControllerAdvice("org.example.controllers")
public class ExampleAdvice2 {}

@ControllerAdvice(assignableTypes = {ControllerInterface.class, AbstractController.class})
public class ExampleAdvice3 {}
profile
Backend Developer

0개의 댓글

Powered by GraphCDN, the GraphQL CDN