이 장에서는 Nex-UP에서 발생하는 예외에 대한 처리 방법과 넥사크로 애플리케이션의 Callback에서 처리할 수 있는 ErrorCode, ErrorMsg를 처리하는 방법에 대해 알아봅니다.
Nex-UP Editor를 통해 개발 된 서비스에 대한 예외처리는 정상적으로 처리되고 있다. 추가적인 비즈니스 로직을 개발하는 경우 아래 예외 처리에 대해 숙지하고 있어야 한다.
개요
예외는 프로그램 개발 시 개발자가 개발해야 하는 항목중 하나 이다.
예외를 정상적으로 처리하지 않으면 반드시 버그가 발생하며, 전혀 예상하지 못하는 잠재적인 버그를 발생 시킬수 있다. 그렇기 때문에 예측가능한 예외에 대해서는 정상적인 예외 처리 및 로깅을 하는것이 필요하다.
nexacro platform에서의 예외처리는 일반적으로 HTTP 상태코드 200(OK)으로 응답하며, ErrorCode, ErrorMsg Variable통해 처리 한다. 다시 말해 서비스에서 발생하는 예외는 처리되어야 하며, 그렇지 않을 경우 nexacro platform의 어플리케이션 레벨인 ADL의 onError에서 처리 된다.
예제 프로젝트는 분산 트랜잭션 처리를 위한 서비스(nexacro.sample..service..*Impl.*(..))에서 예외가 발생 시 분산 트랜잭션 처리가 되도록 되어 있다.
설정 파일 - src/main/resources/spring/context-transaction.xml
예제 프로젝트는 서비스(nexacro.sample..service..*Impl.*(..)) 에서 발생하는 예외를 로깅하고 있다.
설정 파일 - src/main/resources/spring/context-common-exception.xml
개발자가 별도로 처리 하지 않을 경우 Nex-UP은 다음과 같이 처리합니다.
정상 처리
ErrorCode : 0
ErrorMsg : 공백
Exception 발생 시
ErrorCode : -1
ErrorMsg : 예외의 실제 메시지 혹은 'An Error Occured. check the ErrorCode for detail of error infomation'
기본 예외 처리
예제 프로젝트에서의 기본적인 예외처리는 Spring의 HandlerExceptionResolver를 통해 Controller에서 발생하는 예외를 nexacro platform에서 form 단위의 예외처리가 가능하도록 처리되고 있다.
해당 예외에 대한 내용은 dispatcher-servlet.xml에 다음과 같이 등록되어 있다.
... <!-- nexacro exception resolver --> <bean id="exceptionResolver" class="com.nexacro.spring.resolve.NexacroMappingExceptionResolver" p:order="1"> <property name="view" ref="nexacroView" /> <property name="shouldLogStackTrace" value="true" /> <property name="shouldSendStackTrace" value="true" /> <!-- shouldSendStackTrace 가 false 일 경우 nexacro platform으로 전송되는 에러메시지 --> <!-- <property name="defaultErrorMsg" value="An Error Occured. check the ErrorCode for detail of error infomation" /> --> <property name="defaultErrorMsg" value="fail.common.msg" /> <property name="messageSource" ref="messageSource" /> </bean>
위 설정에 대한 내용은 아래와 같다.
exceptionResolver
nexacro platform에서 서비스 요청 시 예외에 대한 처리를 수행한다.
nexacro platform에 대한 요청을 선처리 하기 위해 order를 최우선으로 적용한다.
properties
view - 예외 발생시 사용되는 View
shouldLogStackTrace - 에러정보를 로깅할지 여부 (true | false)
shouldSendStackTrace - 에러정보를 응답으로 전송할지 여부 (true | false), 예외의 실제 메시지를 응답으로 전송할 경우 보안상의 문제가 있을 수 있다. 보안상의 이유로 운영시에는 false로 설정한다.
defaultErrorMsg - shouldSendStackTrace 가 false 일 경우 nexacro platform으로 전송되는 에러메시지, 정의된 메시지 명칭 혹은 값을 입력한다.
messageSource - 메시지를 처리하기 위한 org.springframework.context.MessageSource를 설정한다.
예외 정보 변경
명시적으로 예외 처리 시 다음과 같이 nexacro platform으로 전송하는 예외의 정보(에러코드, 에러메세지)를 변경하여 추가적인 처리 및 메세지 처리를 할수 있다.
다음은 서비스에서 예외를 처리하는 부분에 대한 예이다.
public void process() { try { // some logic... } catch(IOException causeException) { throw new NexacroException( "Resource not found. resource="+resource, // 예외메세지 causeException, // 실제 예외 -8859, // 에러코드 (ErrorCode) "error.resource.invalid"); // 에러메세지 (ErrorMsg) }
예외 처리 상세
com.nexacro.spring.NexacroException의 주요 메서드는 다음과 같다.
public NexacroException(String message)
입력받은 message를 통해 NexacroException을 생성한다.
public NexacroException(String message, Throwable cause)
입력받은 message와 cause를 통해 NexacroException을 생성한다.
public NexacroException(String message, int errorCode, String errorMsg)
입력받은 message, 에러코드, 에러메시지를 통해 NexacroException을 생성한다.
public NexacroException(String message, Throwable cause, int errorCode, String errorMsg)
입력받은 message와 cause, 에러코드, 에러메시지를 통해 NexacroException을 생성한다.
void setErrorCode(int errorCode)
nexacro platform으로 전송 할 에러코드를 설정한다.
설정하지 않을 경우 ‘-1’ 을 전송한다.
void setErrorMsg(String errorMsg)
nexacro platform으로 전송 할 에러메세지를 설정한다.
설정하지 않을 경우 NexacroException 생성 시 전달 받은 메시지를 전송한다.
NexacroMappingExceptionResolver 의 shouldSendStackTrace property 설정 값에 따라 응답으로 전송되는 에러 정보가 달라진다.
shouldSendStackTrace 가 false로 설정되어 있을 경우 예외의 message는 전송되지 않으며, errorMsg(에러메시지) 만 응답으로 전송된다.
에러에 대한 정보는 서버의 로그를 통해 확인한다.
nexacro platform에서의 기본적인 에러처리 형식은 응답헤더 코드는 200(OK)으로 전송되며, 내부에 Variable ( ErrorCode, ErrorMsg )을 통해 처리 한다. transaction 메서드의 콜백 함수에 처리 된다.
그 외 응답코드(4xx, 5xx 등) 에 대한 부분은 ADL 파일의 onerror 이벤트에서 처리 한다.
예외발생 시 추가처리
예외 로깅
예외 처리시 예외에 대한 상세한 정보를 남겨야 하며, 실제 발생한 예외의 정보를 누락해서는 안된다.
아래는 예외 발생 시 로깅에 대한 예이다.
try { // some logic.. } catch(IOException cause) { String message = "second data reading failed. cause=[IOException, message="socket read failed."] , peer='10.10.10.11', port=1234, auth='base1234' thread=11"; logger.error(message); throw new NexacroException(message, cause, -111111, "error.data.read"); }
EgovFramework 예외 처리
http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte:bsl:exception_handling 문서를 참고하여 EgovFramework에서 추가적인 예외처리를 수행한다.
예외 처리에 대한 가이드는 다음문서를 참고한다. http://www.slideshare.net/dhrim/ss-2804901