[43일차] 비즈니스 예외 던지기(throw), 사용자 정의 예외(Custom Exception)

유태형·2022년 6월 29일
0

코드스테이츠

목록 보기
43/77

오늘의 목표

  1. 비즈니스 예외 던지기(throw)
  2. 사용자 정의 예외



내용

비즈니스 예외 던지기(throw)

  • 체크 예외(Checked Exception) : 예외를 catch해서 체크한후 복구 및 회피등 처리를 해야 하는 예외입니다.
  • 언체크 예외(Unchecked Exception) : 어떤 처리를 할 필요가 없는 예외를 의미합니다. RuntimeException 예외는 모두 언체크 예외입니다.

자바 jdk에 내장된 Exception도 유용하지만 서버를 개발하다 보면 다양한 상황에서 다양한 예외를 처리하기 위하여 개발자가 직접 예외를 정의해야 할 수도 있습니다.



throw / catch

throw 키워드를 사용하여 개발자가 임의로 예외를 발생시키면 해당 메서드 밖으로 예외를 던질 수 있습니다. '메서드 밖으로 던진다'라는 의미는 메서드를 호출한 지점으로, 또 그 메서드를 호출한 지점, .... 으로 예외를 받을 때까지 호출한 메서드로 계속 밖으로 던지게 됩니다.

다시 스프링의 @Service클래스에서 발생한 예외는 @Service클래스의 메서드들을 호출하는 @Controller클래스의 헨들러 메서드로 던져지게 됩니다.(@RestControllerAdvice로 이전 가능)

@Service
public class MemberService{
	접근제어자 반환타입 서비스메서드(매개변수){
    	throw new RuntimeException("메시지");
    }
}

하여 서비스 클래스의 메서드에서 예외를 throw하면 원래 @Controller의 핸들러메스드로 에러를 catch하여야 했지만, @RestControllerAdvice어드바이스를 통해 모든 컨트롤러의 예외를 통합하여 관리할 수 있습니다.

@RestControllerAdvice
public class GlobalExceptionAdvice{
	
    @ExceptionHandler
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ErrorResponse handle예외(RuntimeException e){
    	System.out.println(e.getMessage());
        
        return null;
    }
}
  • @RestControllerAdvice : 해당 클래스가 모든 컨트롤러에 던져진 예외를 공통으로 처리하는 어드바이스를 지정합니다.
  • @ExceptionHandler : 해당 메서드가 매개변수로 전달된 예외를 처리하는 메서드임을 명시합니다.
  • @ResponseStatus(HttpStatus.NOT_FOUND) : 응답 코드로 HttpStatus.NOT_FOUND를 고정합니다. 만약 응답 코드가 동적이면 해당 에너테이션을 사용하지 않습니다.
  • RuntimeException.getMessage() : 에러 메세지 내용을 리턴합니다.



사용자 정의 예외

자바에서도 기본으로 많은 예외들을 제공하지만 개발하는 웹의 환경에 따라 또 다양한 상황에서 개발자가 직접 예외를 정의해서 클라이언트에게 알려줄 수 있다면 좀더 유연하고 구체적으로 프로그래밍을 할 수 있을 것 입니다.

코드와 메세지를 가진 예외를 enum 열거형으로 정의하겠습니다.

public enum 사용자정의코드{
	MEMBER_NOT_FOUND(404,"Not Found");
    MEMBER_ALREADY_EXIST(405,"Already Exist"); 
    
    @Getter
    private int status;
    
    @Getter
    private String message;
    
    사용자정의코드(int status, String message){
    	this.status = status;
        this.message = message;
    }
}

enum열거형은 멤버 변수를 가질 수 있습니다. 그리고 멤버 변수들의 데이터를 가진 상수를 정의할 수도 있습니다.

public class 사용자정의예외 extends RuntimeException{
	@Getter
    private 사용자정의코드 열거코드;
    
    public 사용자정의예외(사용자정의코드 열거코드){
    	super(열거코드.getMessage());
        this.열거코드 = 열거코드;
    }
}

사용자 정의 코드와 사용자 정의 코드를 사용하는 사용자 정의 예외를 모두 정의하였다면 @Service에서 예외를 발생시켜 확인할 수 있습니다.

@Service
public class 서비스{
	
    public 리턴타입 서비스메서드(매개변수){
    
    	throw new 사용자정의예외(사용자정의코드.MEMBER_NOT_FOUND);
        //사용자정의코드.MEMBER_ALREADY_EXIST도 가능
    }
}

사용자 정의 에러를 처리하는 @ExceptionHandler를 정의해야 클라이언트에게 에러를 전송할 수 있습니다.

@RestControllerAdvice
public class 어드바이스{
	
    @ExceptionHandler
    public ResponseEntity 에러핸들러(사용자정의예외 e){
    	System.out.println(e.getExceptionCode().getStatus());
        System.out.println(e.getMessage());
        
        return new ResponseEntity<>(HttpStatus.valueOf(e.getExceptionCode(),getStatus()));
    }
}

@ResponseStatus 에너테이션을 제거하고 ResponseEntity로 리턴타입을 수정한 것은 다양한 HttpStatus를 지원하기 위해 수정하였습니다.




후기

어떻게 개발자가 임의로 에러를 발생시키고, 또 임의로 에러를 정의하여 사용하는 것에 대하여 학습하였습니다. 많은 상황에서 다양하게 사용될 것임으로 외우기 보단 흐름을 익혀두어야 겠습니다.




GitHub

없음!

profile
오늘도 내일도 화이팅!

0개의 댓글