본문 바로가기

Spring

스프링에서 예외 처리를 마스터하는 5가지 방법: 안정적인 애플리케이션을 위한 필수 가이드

728x90
반응형

스프링 프레임워크에서 예외 처리(Exception Handling)는 애플리케이션의 안정성과 유지보수를 위해 매우 중요한 부분입니다. 적절한 예외 처리는 사용자에게 유용한 오류 메시지를 전달하고, 시스템 내부의 오류를 안전하게 숨겨 보안을 강화할 수 있습니다. 이 블로그에서는 스프링에서 제공하는 다양한 예외 처리 방법을 살펴보고, 각 방법의 사용 사례를 통해 효율적인 예외 처리 전략을 제시하겠습니다.

1. 전통적인 try-catch 구문

가장 기본적인 예외 처리 방법은 자바의 try-catch 구문을 사용하는 것입니다. 비록 단순하지만, 코드가 예외에 직접 반응할 수 있게 해줍니다. 그러나 이 방식은 코드가 지저분해질 수 있다는 단점이 있습니다.

public void processData() {
    try {
        // 비즈니스 로직
    } catch (Exception ex) {
        // 예외 처리
    }
}

이 방법은 주로 특정 비즈니스 로직에서 예외가 발생할 수 있을 때 사용되지만, 유지보수가 어려워지는 단점이 있어 전역적으로 예외를 처리할 수 있는 다른 방법들이 더 많이 선호됩니다.

2. @ExceptionHandler를 이용한 개별 컨트롤러 예외 처리

스프링에서 예외 처리의 대표적인 방법 중 하나는 @ExceptionHandler 어노테이션을 사용하는 것입니다. 이 방법은 특정 컨트롤러 내에서 발생하는 예외를 처리할 수 있습니다.

@Controller
public class MyController {

    @GetMapping("/data")
    public String getData() {
        // 예외 발생 가능성 있는 로직
        return "data";
    }

    @ExceptionHandler(DataNotFoundException.class)
    public ResponseEntity<String> handleDataNotFound(DataNotFoundException ex) {
        return new ResponseEntity<>("Data not found", HttpStatus.NOT_FOUND);
    }
}

이 방법은 컨트롤러 내부에서 예외를 개별적으로 처리하고 싶을 때 유용하지만, 컨트롤러마다 예외 처리를 반복하게 되면 코드 중복이 발생할 수 있습니다. 이를 보완하기 위해 스프링은 전역적으로 예외를 처리할 수 있는 방법을 제공합니다.

반응형

3. @ControllerAdvice를 이용한 전역 예외 처리

@ControllerAdvice 어노테이션은 모든 컨트롤러에서 발생하는 예외를 전역적으로 처리할 수 있게 해줍니다. 이 방법은 코드 중복을 줄이고 애플리케이션 전반에 일관된 예외 처리 방식을 적용할 수 있는 장점이 있습니다.

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> handleIllegalArgument(IllegalArgumentException ex) {
        return new ResponseEntity<>("Illegal argument: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleGenericException(Exception ex) {
        return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}

@ControllerAdvice는 예외를 중앙에서 관리하여 코드의 일관성과 유지보수성을 높여줍니다. 이를 통해 새로운 예외 처리 정책을 추가하거나 수정할 때도 전체 코드를 수정할 필요가 없게 됩니다.

4. ResponseStatusException을 통한 커스텀 예외 처리

스프링 5에서는 ResponseStatusException 클래스를 도입하여 더욱 간결한 예외 처리가 가능해졌습니다. 이 클래스를 사용하면 커스텀 예외를 손쉽게 처리하고, 특정 HTTP 상태 코드를 반환할 수 있습니다.

@GetMapping("/resource/{id}")
public Resource getResource(@PathVariable Long id) {
    return repository.findById(id).orElseThrow(() -> 
        new ResponseStatusException(HttpStatus.NOT_FOUND, "Resource not found"));
}

5. Custom Exception과 @ResponseStatus를 활용한 예외 처리

때로는 애플리케이션에서 커스텀 예외를 만들어서 처리하는 것이 더 명확할 때가 있습니다. @ResponseStatus 어노테이션을 사용하면 커스텀 예외에 HTTP 상태 코드를 직접 지정할 수 있습니다.

@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}

@GetMapping("/item/{id}")
public Item getItem(@PathVariable Long id) {
    return itemRepository.findById(id).orElseThrow(() -> 
        new ResourceNotFoundException("Item not found"));
}

이 방법은 커스텀 예외를 사용하여 코드 가독성을 높일 수 있으며, 예외를 통한 비즈니스 로직의 흐름을 명확하게 표현할 수 있는 장점이 있습니다.

728x90

스프링에서 예외 처리는 단순한 오류 메시지 출력 이상의 역할을 합니다. 적절한 예외 처리는 사용자 경험을 개선하고, 코드의 유지보수성을 높이며, 보안성을 강화하는 데 중요한 역할을 합니다. 이번 블로그에서 소개한 다양한 예외 처리 방법들을 애플리케이션의 특성에 맞게 적절히 조합하여 사용한다면, 더욱 안정적이고 효율적인 예외 처리가 가능할 것입니다.

728x90
반응형