Project

[stock] 완성도 높이기 - 예외 처리

sangyunpark 2023. 9. 27. 19:21

에러가 나지 않는 것 뿐만 아니라,

에러를 잘 발생시켜 주는 것도 중요하다.

 

예외를 발생시키는 코드를 작성해보자!

 

AbstractException

package com.example.stock.exception;

public abstract class AbstractException extends RuntimeException{
    abstract public int getStatusCode();
    abstract public String getMessage();
}

추상 클래스를 두어 다양한 예외들이 상속을 받는 구조로 한다.

 

AlreadyExistUserException

package com.example.stock.exception.impl;

import com.example.stock.exception.AbstractException;
import org.springframework.http.HttpStatus;

public class AlreadyExistUserException extends AbstractException {
    @Override
    public int getStatusCode() {
        return HttpStatus.BAD_REQUEST.value();
    }

    @Override
    public String getMessage() {
        return "이미 존재하는 사용자 명입니다.";
    }
}

이런식으로 상속을 받아 선언한다.

위 예외는 이미 유저가 존재하는 경우 발생하는 예외이다.

 

NoCompanyException

package com.example.stock.exception.impl;

import com.example.stock.exception.AbstractException;
import org.springframework.http.HttpStatus;

public class NoCompanyException extends AbstractException {
    @Override
    public int getStatusCode() {
        return HttpStatus.BAD_REQUEST.value(); // 400
    }

    @Override
    public String getMessage() {
        return "존재하지 않는 회사명 입니다.";
    }
}

회사가 존재하지 않는 경우 발생하는 에러이다.

 

단순히 에러만 클래스로 만들어준다고 해서 사용할 수 있는 것은 아니다.

 

커스텀 에러를 사용하려면 핸드러가 필요하다.

package com.example.stock.exception;


import lombok.extern.slf4j.Slf4j;
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 java.util.Objects;

@Slf4j
@ControllerAdvice // Filter와 비슷하게 Controller 코드보다 조금 더 바깥(Controller 레이어와 가까운 위치) | 필터가 훨씬 더 바깥
public class CustomExceptionHandler { // Controller

    @ExceptionHandler(AbstractException.class)
    protected ResponseEntity<ErrorResponse> handleCustomException(AbstractException e) {

        ErrorResponse errorResponse = ErrorResponse.builder()
                .code(e.getStatusCode())
                .message(e.getMessage())
                .build();

        return new ResponseEntity<>(errorResponse,HttpStatus.resolve(e.getStatusCode()));
    }
}

 

ResponseEntity

package com.example.stock.exception;

import lombok.Builder;
import lombok.Data;

@Data
@Builder
public class ErrorResponse {
    private int code;
    private String message;
}

 

이제 에러가 발생하면, 다음과 같이 된다.

 

야호~!