오늘도 삽질중

spring ExceptionHandler Response remove stackTrace, cause 본문

스프링

spring ExceptionHandler Response remove stackTrace, cause

Choi3950 2023. 9. 10. 16:59
반응형

예외처리를 전역적으로 사용하기 위해  @ExceptionHandler 를 사용해 처리하곤 합니다.

아래처럼 말이죠

    @ExceptionHandler(InvalidDataAccessApiUsageException.class)
    public ResponseEntity<?> handle(InvalidDataAccessApiUsageException exception, WebRequest request){
        return new ResponseEntity<>(
                new ApiException(ApiError.COMPANY_IS_NULL),
                HttpStatus.BAD_REQUEST
        );
    }

 

이렇게 설정을 한 후 테스트를 하다보면 아래 포맷으로 에러 메시지가 나오는 경우가 있습니다.

{
    "cause": null,
    "stackTrace": [
        {
            "classLoaderName": "app",
            "moduleName": null,
            "moduleVersion": null,
            "methodName": "applyOrder",
            "fileName": "TransactionService.java",
            "lineNumber": 183,
            "nativeMethod": false,
            "className": "com.kipit.wallet.banking.transaction.TransactionService"
        },
       
    ],
    "type": "https://www.kipit.ir/problem/problem-with-message",
    "title": "OrderNotFoundException",
    "status": "BAD_REQUEST",
    "detail": null,
    "instance": null,
    "parameters": {},
    "message": "OrderNotFoundException",
    "suppressed": [],
    "localizedMessage": "OrderNotFoundException"
}

 

Response 응답에 cause, stackTrace 가 포함되는 경우가 있습니다.

저도 이렇게 나오는 경우가 있어서 30분정도 허비 했는데 의미없는 삽질이였습니다.

 

보통 ApiException 과 같은 커스텀 클래스를 만들어서 상황에 맞게 Throw 처리를 많이들 하실껍니다.

ApiException 의 클래스는 RuntimeException을 상속받고 아래처럼 구성되있습니다.

 

public class ApiException extends RuntimeException {

    private final int status;
    private final String resultCode;
    private final ApiError apiError;
    
    ....
    ....

 

결론부터 말씀드리면 ResponseEntity 리턴 파라미터가 RuntimeException 을 상속 받은 클래스를 넣을 경우 응답에 cause,stackTrace 가 포함됩니다.

그래서 RuntimeException을 상속 받지 않는 별도의 에러 포맷 클래스를 아래처럼 작성하였습니다.

@Getter
@AllArgsConstructor
public class ApiErrorResponse {
    private final String resultCode;
    private final String message;

    public ApiErrorResponse(ErrorSpec errorSpec) {
        this.resultCode = errorSpec.getResultCode();
        this.message = errorSpec.getMessage();
    }
}

 

이후에 ReposnseEntity 응답을 교체하였습니다.

    @ExceptionHandler(InvalidDataAccessApiUsageException.class)
    public ResponseEntity<?> handle(InvalidDataAccessApiUsageException exception, WebRequest request){

        return new ResponseEntity<>(
                new ApiErrorResponse(null,ExceptionMessage.BAD_REQUEST),
                HttpStatus.BAD_REQUEST
        );
    }

 

교체 후 응답 확인 결과 제가 원하는 포맷대로 정상 출력됨을 확인했습니다.

반응형

'스프링' 카테고리의 다른 글

spring SQL injection 방지 (with. paging sort dynamic query)  (0) 2023.09.10
Comments