Repository navigation
fix: BaseException·BaseRuntimeException 이 전달받은 원인 예외를 보관하지 않아 getWrappedException() 이 항상 null 인 문제 수정 - #350
Merged
jei007 merged 1 commit intoAug 24, 2026
Conversation
…pedException() 이 항상 null 인 문제 수정 BaseException 과 BaseRuntimeException 은 protected Exception wrappedException 필드와 getWrappedException() 접근자를 제공한다. 그런데 원인 예외를 받는 모든 생성자가 super(wrappedException) 만 호출하고 이 필드에는 대입하지 않는다. 저장소 전체에서 이 필드에 대입하는 곳은 setWrappedException() 하나뿐이므로, 생성자로 원인 예외를 넘겨도 getWrappedException() 은 항상 null 을 반환한다. getCause() 는 정상 동작하므로 같은 객체에서 두 접근자가 서로 다른 값을 준다. 대입이 빠진 이유는 타입 폭이 맞지 않기 때문이다. 필드는 Exception 인데 생성자 파라미터는 Throwable 이라 그대로 대입하면 컴파일되지 않는다. EgovBizException 과 EgovBatchException 은 파라미터를 Exception 으로 선언해 같은 필드에 대입하고 있으며, 그래서 이 두 클래스에서는 접근자가 정상이다. 필드와 접근자 시그니처를 바꾸지 않고 종단 생성자에서 instanceof 로 좁혀 대입했다. 필드 타입을 Throwable 로 넓히는 방법도 있으나 protected 필드라 이 필드를 Exception 으로 참조하는 하위 클래스의 컴파일을 깨뜨릴 수 있어 선택하지 않았다. Error 나 Exception 이 아닌 Throwable 이 원인으로 전달되는 경우 이 필드에는 담기지 않지만 getCause() 로는 그대로 조회된다. FdlException 은 종단 생성자가 super(wrappedException) 로 BaseException 의 생성자를 호출하므로 별도 수정 없이 함께 해소된다. 회귀 테스트로 확인했다. 영향 범위는 이 두 클래스를 직접 생성하는 경로다. ExceptionTransfer 는 분류되지 않은 예외를 BaseException 으로 재생성해 던지고, EgovExcelServiceImpl 은 BaseRuntimeException 을 원인 예외와 함께 7곳에서 던진다. 후처리 핸들러가 getWrappedException() 으로 원인을 조회하는 경우 지금까지는 값을 받지 못했다. 저장소에 포함된 핸들러 예제도 이 접근자를 사용한다. 최초 커밋부터 이 필드가 생성자에서 채워진 적이 없어 기존 값에 의존하던 코드는 없다. 검증 - 신규 테스트 7건 추가. BaseException·BaseRuntimeException·FdlException 각 두 종류 생성자에서 getWrappedException() 과 getCause() 가 전달한 객체와 동일한지 확인하고, 원인 예외를 넘기지 않은 경우 null 인 것도 확인한다. - 수정을 되돌리면 신규 테스트 6건이 전부 null 로 실패한다. - org.egovframe.rte.fdl.cmmn 38건 통과. - 이 두 클래스를 사용하는 모듈 회귀: fdl.excel 33건, fdl.idgnr 42건, bat.core 86건 전부 통과.
jei007
approved these changes
Aug 24, 2026
jei007
left a comment
Contributor
There was a problem hiding this comment.
표준프레임워크에 대한 지속적인 참여에
대단히 감사드립니다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
수정 사유 Reason for modification
소스를 수정한 사유가 무엇인지 체크해 주세요. Please check the reason you modified the source. ([X] X는 대문자여야 합니다.)
수정된 소스 내용 Modified source
BaseException과BaseRuntimeException은protected Exception wrappedException필드와getWrappedException()접근자를 제공합니다. 그런데 원인 예외를 받는 모든 생성자가super(wrappedException)만 호출하고 이 필드에는 대입하지 않습니다. 저장소 전체에서 이 필드에 대입하는 곳은setWrappedException()하나뿐이므로, 생성자로 원인 예외를 넘겨도getWrappedException()은 항상null을 반환합니다.getCause()는 정상 동작하므로 같은 객체에서 두 접근자가 서로 다른 값을 주는 상태입니다.대입이 빠진 이유는 타입 폭이 맞지 않기 때문입니다. 필드는
Exception인데 생성자 파라미터는Throwable이라 그대로 대입하면 컴파일되지 않습니다. 반면EgovBizException과EgovBatchException은 파라미터를Exception으로 선언해 같은 필드에 대입하고 있고, 그래서 이 두 클래스에서는 접근자가 정상 동작합니다. 이 두 클래스는 각각 #341 과 #307 에서 원인 예외 전달이 정리되었으며, 이번 수정은 그 상위 클래스에 남아 있던 같은 성격의 문제를 다룹니다.수정 방법은 필드와 접근자 시그니처를 그대로 두고 종단 생성자에서
instanceof로 좁혀 대입하는 방식을 선택했습니다.필드 타입을
Throwable로 넓히는 방법도 검토했으나,protected필드이므로 이 필드를Exception으로 참조하는 하위 클래스가 있다면 컴파일이 깨질 수 있어 선택하지 않았습니다. 저장소 안에서 이 필드를 읽는 하위 클래스는 없고EgovBizException과EgovBatchException이 대입만 하고 있으나, 저장소 밖의 사용 여부는 확인하지 못했습니다.Error나Exception이 아닌Throwable이 원인으로 전달되는 경우 이 필드에는 담기지 않지만getCause()로는 그대로 조회됩니다.FdlException은 종단 생성자가super(wrappedException)으로BaseException의 생성자를 호출하므로 별도 수정 없이 함께 해소됩니다. 회귀 테스트에 이 경우도 포함했습니다.영향 범위는 이 두 클래스를 직접 생성하는 경로입니다.
ExceptionTransfer는 분류되지 않은 예외를BaseException으로 재생성해 던지고(ExceptionTransfer.javaprocessException),EgovExcelServiceImpl은BaseRuntimeException을 원인 예외와 함께 7곳에서 던집니다. 후처리 핸들러가getWrappedException()으로 원인을 조회하는 경우 지금까지는 값을 받지 못했습니다. 저장소에 포함된 핸들러 예제OthersServiceExceptionHandler도 이 접근자를 사용합니다.최초 커밋부터 이 필드가 생성자에서 채워진 적이 없어, 기존에 이 값을 받아 동작하던 코드는 없습니다.
변경 규모는 소스 2파일 각 6줄, 테스트 1파일 신규입니다.
JUnit 테스트 JUnit tests
테스트를 완료하셨으면 다음 항목에 [대문자X]로 표시해 주세요. When you're done testing, check the following items.
신규 테스트
WrappedExceptionRetentionTest7건을 추가했습니다.BaseException·BaseRuntimeException·FdlException각각에 대해 기본 메시지 생성자와MessageSource생성자 두 경로에서getWrappedException()과getCause()가 전달한 객체와 동일한지 확인하고, 원인 예외를 넘기지 않은 생성자에서는null인 것도 함께 확인합니다.수정을 되돌린 상태에서 신규 테스트를 실행하면 6건이 전부
expected: <java.lang.IllegalStateException: ...> but was: <null>로 실패하고, 원인 예외를 넘기지 않는 1건만 통과합니다.측정 환경은 JDK 21, Maven 3.9.16 입니다.
Foundation/org.egovframe.rte.fdl.cmmnFoundation/org.egovframe.rte.fdl.excelFoundation/org.egovframe.rte.fdl.idgnrBatch/org.egovframe.rte.bat.corefdl.excel과fdl.idgnr은 각각BaseRuntimeException과FdlException을 사용하는 모듈이고,bat.core는BaseRuntimeException을 상속한EgovBatchException을 사용하는 모듈이라 회귀 확인 대상에 포함했습니다.테스트 브라우저 Test Browser
테스트를 진행한 브라우저를 선택해 주세요. Please select the browser(s) you ran the test on. (다중 선택 가능 you can select multiple) [X] X는 대문자여야 합니다.
예외 클래스의 생성자 동작 변경이라 화면 동작과 무관하여 브라우저 테스트는 진행하지 않았습니다.
테스트 스크린샷 또는 캡처 영상 Test screenshots or captured video
화면 변경이 없어 스크린샷을 첨부하지 않았습니다. 대신 수정 전후 동작 차이를 아래 표로 정리했습니다. 각 클래스에 원인 예외를 생성자로 전달한 뒤 두 접근자를 조회한 결과입니다.
getWrappedException()getWrappedException()getCause()(수정 전후 동일)BaseExceptionnullBaseRuntimeExceptionnullFdlExceptionnullEgovBizException