서버/Spring boot

#에러처리

paran21 2022. 2. 7. 19:23

예측이 가능한 에러를 exception처리를 하고 나서 HTTP status와 errorMessage를 보내줄 수 있다.

예를 들어, 클라이언트에서 입력값과 관련된 에러는 500 Internel Server Error가 아니라 400 Bad Request + 에러메세지를 보내서 어떤 부분에서 에러가 난 것인지 알려줄 수 있다.

프론트에서는 이 메세지를 활용해 팝업 등으로 보여줄 수 있다.

 

스프링에서 제공하는 ResponseEntity를 사용하면 HTTP status Code, HTTP headers, HTTP body를 선언할 수 있다.

그리고 이 클래스를 이용하여 원하는 내용을 클라이언트로 보낼 수 있다.

package com.sparta.week03project.exception;

import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpStatus;

@Getter
@Setter
public class RestApiException {
    private String errorMessage;
    private HttpStatus httpStatus;
}

 

에러를 보내는 방법은 다음 3가지가 있다.

1) try catch 사용하기

controller에서 원하는 부분에 try catch를 사용해서 에러가 발생하지 않은 경우에는 HttpStatus.OK를, 에러가 발생하면 위의 클래스를 통해 Bad Request와 error message를 보낼 수 있다.

이 방법은 해당 메소드 안에서만 적용이 된다.

@PostMapping("api/folders") 
public ResponseEntity addFolders(@RequestBody FolderRequestDto folderRequestDto, 
								@AuthenticationPrincipal UserDetailsImpl userDetails ) {
       try {
       		List<String> folderNames = folderRequestDto.getFolderNames();
			User user = userDetails.getUser();
			List<Folder> folders = folderService.addFolders(folderNames, user);
			return new ResponseEntity(folders, HttpStatus.OK);
		} catch(IllegalArgumentException ex) {
        	RestApiException restApiException = new RestApiException();
			restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
			restApiException.setErrorMessage(ex.getMessage());
			return new ResponseEntity( 
            	// HTTP body 
                restApiException, 
                // HTTP status code
				HttpStatus.BAD_REQUEST);
		} 
}

2) @ExceptionHandler 사용

해당 controller의 모든 함수에 적용할 수 있다.(AOP)

@ExceptionHandler({ IllegalArgumentException.class }) 
public ResponseEntity handleException(IllegalArgumentException ex) {
	RestApiException restApiException = new RestApiException();
	restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
	restApiException.setErrorMessage(ex.getMessage());
	return new ResponseEntity( 
    	// HTTP body 
        restApiException, 
        // HTTP status
        code HttpStatus.BAD_REQUEST );
}

3) Global 예외처리

@ControllerAdvice를 사용하여 공통으로 적용되는 ExceptionHandler를 만들 수 있다.

@RestControllerAdvice : @ControllerAdvice + @ResponseBody

아래와 같이 적용하면 IllegalArgumentException과 NullPointerException을 모두 400 Bad Request + 에러 메시지를 보낼 수 있다.

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class RestApiExceptionHandler {

    @ExceptionHandler(value = { IllegalArgumentException.class })
    public ResponseEntity<Object> handleApiRequestException(IllegalArgumentException ex) {
        RestApiException restApiException = new RestApiException();
        restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
        restApiException.setErrorMessage(ex.getMessage());

        return new ResponseEntity(
                restApiException,
                HttpStatus.BAD_REQUEST
        );
    }

    @ExceptionHandler(value = { NullPointerException.class })
    public ResponseEntity<Object> handleApiRequestException(NullPointerException ex) {
        RestApiException restApiException = new RestApiException();
        restApiException.setHttpStatus(HttpStatus.BAD_REQUEST);
        restApiException.setErrorMessage(ex.getMessage());

        return new ResponseEntity(
                restApiException,
                HttpStatus.BAD_REQUEST
        );
    }
}

그리고 여기에 Error Code를 사용하면 error를 세분화하여 정의해줄 수 있다.

'서버 > Spring boot' 카테고리의 다른 글

#CORS 설정하기  (0) 2022.02.12
#AOP  (0) 2022.02.07
#ORM, JPA, Spring data JPA, SQL  (0) 2022.02.05
#Spring security  (0) 2022.01.28
#DI, IoC, Bean  (0) 2022.01.28