과정을 즐기자

예외 본문

Spring

예외

320Hwany 2023. 4. 3. 17:12

이 글은 토비의 스프링을 읽고 작성한 글입니다.  

 

try {

    ...

} catch (SQLException e){            
}

위와 같은 코드의 문제점은 예외를 잡고는 아무것도 하지 않았다는 점입니다. 예외는 반드시 처리되어야 합니다.
예외를 처리할 때 반드시 지켜야 할 핵심 원칙은 모든 예외는 적절하게 복구되든지 아니면 작업을 중단시키고
운영자 또는 개발자에게 분명하게 통보되어야 한다는 것입니다.

 

예외를 처리하기 전에 우선 체크 예외와 언체크 예외에 대해서 알아야합니다.

 

GitHub - 320Hwany/TIL

Contribute to 320Hwany/TIL development by creating an account on GitHub.

github.com

자세한 내용은 위 링크에 있지만 간단하게 요약하면 체크 예외가 발생할 수 있는 메소드를 사용할 경우  

반드시 예외를 처리하는 코드를 함께 작성해야 합니다.  언체크 예외는 따로 처리하지 않아도 됩니다.  

 

예외처리 방법

1. 예외 복구 

 

첫번째 예외처리 방법은 예외상황을 파악하고 문제를 해결해서 정상 상태로 돌려놓는 것입니다.  

예외처리 코드를 강제하는 체크 예외들은 예외를 어떤 식으로든 복구할 가능성이 있는 경우에 사용합니다.  

 

2. 예외처리 회피

 

두번째 방법은 예외처리를 자신이 담당하지 않고 자신을 호출한 쪽으로 던져버리는 것입니다.  

하지만 이 방법은 템플릿 콜백 관계처럼 긴밀한 관계에 있는 다른 오브젝트에게 예외처리 책임을  

분명히 지게하거나 사용하는 쪽에서 예외를 다루는 것이 최선의 방법일 때 사용해야 합니다.  

 

3. 예외 전환

 

발생한 예외를 그대로 넘기는 것이 아니라 적절한 예외로 전환해서 던진다는 특징이 있습니다.  

의미를 명확하게 하려고 바꿔서 전달하는 경우도 있지만 주로 예외처리를 강제하는 체크 예외를  

언체크 예외인 런타임 예외로 바꾸는 경우에 사용합니다.

 

만약 어차피 복구가 불가능한 예외라면 가능한 한 빨리 런타임 예외로 포장해 던지게 해서 다른 계층의

메소드를 작성할 때 불필요한 throws 선언이 들어가지 않도록 해주는 것이 바람직합니다.

 

예외처리 전략

체크 예외는 복구할 가능성이 조금이라도 있는 상황에서 자바는 이를 처리하는 catch 블록이나

throws 선언을 강제하고 있습니다.  

사용자와 바로 커뮤니케이션 하면서 예외를 복구하는 독립형 애플리케이션의 경우에는 이 방법이 괜찮지만  

서버의 특정 계층에서 예외가 발생했을 때는 적절하지 않습니다.

사용자와 커뮤니케이션하면서 복구할 방법이 없기 때문에 해당 사용자 요청의 작업만 중단시키는 것이

적절한 방법입니다. 따라서 대응이 불가능한 체크 예외라면 빨리 런타임 예외로 전환해서 던지는게 더 좋은 방법입니다.

 

사용 예시

실제로 어떠한 예시가 있는지 확인해보겠습니다.  이미지를 서버에 저장하는 로직이 있을 때  

transferTo()라는 메소드를 사용하는데 이는 체크 예외인 IOException를 던집니다.  

이는 복구할 수 없는 예외입니다. 따라서 가능한 한 빨리 런타임 예외로 바꿔야 합니다.

이를 런타임 예외인 ImgUploadException으로 바꿔서 던졌습니다.  

이제 imgUploadOnServer() 메소드가 다른 계층에서 사용되더라도 런타임 예외이기 때문에

무분별한 throws 선언을 피할 수 있습니다.  

 

ImgUploadException

@Getter
public class ImgUploadException extends RuntimeException {

    private final String statusCode = BAD_REQUEST;
    private static final String MESSAGE = IMG_UPLOAD_BAD_REQUEST.getValue();

    public ImgUploadException() {
        super(MESSAGE);
    }
}

ImgUploadOnServer

public static void imgUploadOnServer(MultipartFile uploadImg, String imgDir) {
    String fullPath = imgDir + uploadImg.getOriginalFilename();
    try {
        uploadImg.transferTo(new File(fullPath));
    } catch (IOException e) {
        throw new ImgUploadException();
    }
}

 

 

출처 : 토비의 스프링 3.1 Vol.1 스프링의 이해와 원리

'Spring' 카테고리의 다른 글

[Spring Boot] 이메일로 사용자 인증하기  (0) 2023.04.22
서비스 추상화  (0) 2023.04.11
템플릿  (0) 2023.04.02
테스트  (0) 2023.03.26
오브젝트와 의존관계  (0) 2023.03.25