반응형
개발을 하다가 문득 exception에 에러 메시지 성공 메시지 등을 뿌려주지를 않는,, 기이한 현상을 발견했다. 화면 개발자 입장에서는 생각해보면 당연한거였는데 혼자 다 하려다보니까 이러한 에러 메시지는 JAVA에서만 처리를 해놓고 그 메시지를 화면에 뿌려줘야하는 것을 까먹고 있었다. 그래서 Exception에 대한 처리를 추가했다.
우선 패키지 구조는 @SpringBootApplication이 선언된 하위 패키지이다.

구조는 exception이라는 폴더를 만들어서 진행를 하려고한다.
우선 가장 먼저 BusinessException , GlobalExceptionHandler라는 파일을 만들겠다.
BusinessException 파일 소스
package com.test.gw.exception;
/**
* 비즈니스 규칙 위반 시 사용하는 커스텀 예외
*
* - 서버 장애(Exception)와 구분하기 위함
* - 예: 고객 중복, 필수값 누락, 상태상 저장 불가 등
* - GlobalExceptionHandler에서 잡아서 400(Bad Request)로 내려줌
*/
public class BusinessException extends RuntimeException {
/**
* @param message 프론트엔드에 그대로 전달할 사용자용 메시지
*/
public BusinessException(String message) {
super(message);
}
}
GlobalExceptionHandler.java 파일 소스
package com.test.gw.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Map;
/**
* 전역 예외 처리 클래스
*
* - Controller / Service 어디에서 발생한 예외든 여기서 공통 처리
* - 프론트엔드에 내려줄 HTTP 상태 코드와 메시지를 표준화
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 비즈니스 예외 처리
*
* - BusinessException은 "사용자 입력/상태 문제"
* - HTTP 400 (Bad Request)로 응답
* - message는 프론트에서 alert / toast로 그대로 사용
*/
@ExceptionHandler(BusinessException.class)
public ResponseEntity<?> handleBusinessException(BusinessException e) {
return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(Map.of(
"code", "BUSINESS_ERROR", // 프론트 분기용 코드
"message", e.getMessage() // 실제 사용자 메시지
));
}
/**
* 그 외 모든 예외 처리 (예상하지 못한 서버 오류)
*
* - NullPointerException, SQLException 등
* - HTTP 500 (Internal Server Error)
* - 실제 오류 메시지는 로그로만 남기고,
* 사용자에게는 공통 메시지 제공
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<?> handleException(Exception e) {
return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR) // 500
.body(Map.of(
"code", "SERVER_ERROR",
"message", "서버 오류가 발생했습니다."
));
}
}
service단에서 실제 사용예시이다.
// BusinessException에 대한 처리이다.
if (dup != null) {
throw new BusinessException(
"이미 다른 품목에서 사용 중인 LOT 번호입니다. (LOT: " + noLot + ")"
);
}
실제로 프론트엔드에서 뿌려지는 문구를 확인해보자. 저장 버튼 클릭시 번호가 중복되면은 문구를 띄워줬다.
네트워크 상태를 보면은 정상적으로 넘어온게 확인이된다.

try {
const listAction = await dispatch(
getTestList({...searchParams, test: selectedRow?.test ?? testList?.[0]?.test ?? ""})
);
const payload = listAction.payload as Payload;
if (payload.status === 200 && payload.data) {
console.log(payload);
}
showAlert("저장되었습니다.");
} catch (err) {
let message = "저장에 실패했습니다.";
// 에러문구는 여기서 표출을 시켜준다.
if (typeof err === "object" && err !== null) {
const anyErr = err as any;
message =
anyErr?.message ??
anyErr?.response?.data?.message ??
message;
}
showAlert(message);
}
};

반응형
'JAVA' 카테고리의 다른 글
| [JAVA] @JsonProperty 사용 이유 (0) | 2025.12.30 |
|---|---|
| [JAVA] Naver News API 적용 (2) | 2025.08.26 |
| [Java] 이미지 미리보기 C: 경로에 있는 파일 불러오기 (1) | 2025.07.04 |
| [JAVA] application.properties에서 log 설정 (1) | 2025.05.27 |
| [JAVA] 파일 다운로드 API 간단하게 구현 + Front End 다운로드 기능 까지. (0) | 2025.04.21 |