2.3. 예외 처리
초록
Apache Camel은 다양한 수준의 세분성에서 예외를 처리할 수 있는 여러 가지 메커니즘을 제공합니다. doTry를 사용하여 경로 내에서 예외를 처리할 수 있습니다. doTry
,doCatch
, doFinally
; 또는 각 예외 유형에 대해 수행할 작업을 지정하고 이 규칙을 Exception
을 사용하여 RouteBuilder
의 모든 경로에 적용할 수 있습니다. 또는 모든 예외 유형에 대해 수행할 작업을 지정하고 errorHandler
를 사용하여 RouteBuilder
의 모든 경로에 이 규칙을 적용할 수 있습니다.
예외 처리에 대한 자세한 내용은 6.3절. “dead Letter Channel” 을 참조하십시오.
2.3.1. onException Clause
2.3.1.1. 개요
절은 하나 이상의 경로에서 발생하는 예외를 트래핑하기 위한 강력한 메커니즘입니다. 즉, 유형별로 다른 예외 유형을 처리할 수 있는 고유한 작업을 정의할 수 있습니다. 따라서 기본적으로 동일한(실제로 확장) 구문을 사용하여 작업을 정의할 수 있으므로 예외를 처리하는 방식에 상당한 유연성을 제공하고 예외를 처리하는 방식에 상당한 유연성을 제공하고, 예외를 처리할 수 있습니다.
onException
2.3.1.2. onException을 사용하여 예외를 트래핑
onException
절은 예외를 catch하는 대신 트래핑 을 위한 메커니즘입니다. 즉, onException
절을 정의하면 경로의 모든 지점에서 발생하는 예외를 트랩합니다. 이는 특정 코드 조각이 try 블록으로 명시적으로 묶은 경우에만 예외가 발생하는 Java try/catch 메커니즘과 대조됩니다.
onException
절을 정의할 때 실제로 발생하는 것은 Apache Camel 런타임이 try 블록의 각 경로 노드를 암시적으로 묶는 것입니다. 따라서 onException
절은 경로의 어느 시점에서 예외를 트래킹할 수 있습니다. 그러나 이 래핑은 자동으로 수행됩니다. 경로 정의에는 표시되지 않습니다.
2.3.1.3. Java DSL 예
다음 Java DSL 예제에서 onException
절은 RouteBuilder
클래스에 정의된 모든 경로에 적용됩니다. If a ValidationException
exception occurs while processing either of the routes (from("seda:inputA")
or from("seda:inputB")
, the onException
clause traps the exception and redirects the current exchange to the validationFailed
JMS queue (which serves as a deadletter queue).
// Java public class MyRouteBuilder extends RouteBuilder { public void configure() { onException(ValidationException.class) .to("activemq:validationFailed"); from("seda:inputA") .to("validation:foo/bar.xsd", "activemq:someQueue"); from("seda:inputB").to("direct:foo") .to("rnc:mySchema.rnc", "activemq:anotherQueue"); } }
2.3.1.4. XML DSL 예
위 예제는 다음과 같이 onException
요소를 사용하여 예외 절을 정의하는 XML DSL로 표시할 수도 있습니다.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <onException> <exception>com.mycompany.ValidationException</exception> <to uri="activemq:validationFailed"/> </onException> <route> <from uri="seda:inputA"/> <to uri="validation:foo/bar.xsd"/> <to uri="activemq:someQueue"/> </route> <route> <from uri="seda:inputB"/> <to uri="rnc:mySchema.rnc"/> <to uri="activemq:anotherQueue"/> </route> </camelContext> </beans>
2.3.1.5. 여러 예외를 트랩
RouteBuilder
범위에서 예외를 해결하기 위해 여러 onException
절을 정의할 수 있습니다. 이를 통해 다양한 예외에 대한 응답으로 다양한 작업을 수행할 수 있습니다. 예를 들어 Java DSL에 정의된 다음과 같은 onException
절에서는 ValidationException
,IOException
및 Exception
에 대해 서로 다른 deadletter 대상을 정의합니다.
onException(ValidationException.class).to("activemq:validationFailed"); onException(java.io.IOException.class).to("activemq:ioExceptions"); onException(Exception.class).to("activemq:exceptions");
다음과 같이 XML DSL에서 동일한 일련의 onException
절을 정의할 수 있습니다.
<onException> <exception>com.mycompany.ValidationException</exception> <to uri="activemq:validationFailed"/> </onException> <onException> <exception>java.io.IOException</exception> <to uri="activemq:ioExceptions"/> </onException> <onException> <exception>java.lang.Exception</exception> <to uri="activemq:exceptions"/> </onException>
여러 예외를 함께 그룹화하여 동일한 onException
절에 의해 갇힐 수도 있습니다. Java DSL에서는 다음과 같이 여러 예외를 그룹화할 수 있습니다.
onException(ValidationException.class, BuesinessException.class) .to("activemq:validationFailed");
XML DSL에서는 다음과 같이 onException
요소 내에 두 개 이상의 예외
요소를 정의하여 함께 여러 예외를 그룹화할 수 있습니다.
<onException> <exception>com.mycompany.ValidationException</exception> <exception>com.mycompany.BuesinessException</exception> <to uri="activemq:validationFailed"/> </onException>
여러 예외를 트랩핑할 때 onException
절의 순서가 중요합니다. Apache Camel은 처음에 첫 번째 절에 대해 throw된 예외와 일치하려고 시도합니다. 첫 번째 절이 일치되지 않으면 다음 onException
절이 시도된 후 일치 항목이 발견될 때까지 계속 실행됩니다. 일치하는 각 시도는 다음 알고리즘에 의해 관리됩니다.
throw된 예외가 체인된 예외 (즉, 예외가 catch되고 다른 예외로 다시 탐색된 경우)인 경우 가장 중첩된 예외 유형은 처음에 일치의 기반으로 사용됩니다. 이 예외는 다음과 같이 테스트됩니다.
-
예외-투-테스트에 정확히
onException
절에 지정된 형식이 있는 경우(인스턴스를
사용하여 테스트됨) 일치가 트리거됩니다. -
예외-투-테스트가
onException
절에 지정된 형식의 하위 유형인 경우 일치가 트리거됩니다.
-
예외-투-테스트에 정확히
- 가장 중첩된 예외가 일치를 산출하지 못하면 체인의 다음 예외(래핑 예외)가 대신 테스트됩니다. 테스트는 일치가 트리거되거나 체인이 소진될 때까지 체인을 계속합니다.
throwException EIP를 사용하면 간단한 언어 표현식에서 새 예외 인스턴스를 만들 수 있습니다. 예를 들어 현재 교환에서 사용 가능한 정보를 기반으로 동적으로 만들 수 있습니다.
<throwException exceptionType="java.lang.IllegalArgumentException" message="${body}"/>
2.3.1.6. Deadletter 채널
onException
사용의 기본 예제는 지금까지 모두 deadletter 채널 패턴을 악용했습니다. 즉, onException
절이 예외를 트래핑할 때 현재 교환은 특수 대상(종종 채널)으로 라우팅됩니다. deadletter 채널은 처리되지 않은 실패한 메시지의 보관 영역 역할을 합니다. 관리자는 나중에 메시지를 검사하고 어떤 작업을 수행해야 하는지 결정할 수 있습니다.
deadletter 채널 패턴에 대한 자세한 내용은 6.3절. “dead Letter Channel” 을 참조하십시오.
2.3.1.7. 원본 메시지 사용
경로 중간에서 예외가 발생하는 시점에, 교환의 메시지는 상당히 수정될 수 있었습니다(하나의 사람이 읽을 수도 있음). 경로 시작 시 수신되는 대로 문자 큐에 표시되는 메시지가 원본 메시지인 경우 관리자가 수행할 수정 작업을 보다 쉽게 결정할 수 있습니다. useOriginalMessage
옵션은 기본적으로 false
이지만 오류 처리기에 구성된 경우 자동으로 활성화됩니다.
useOriginalMessage
옵션을 사용하면 여러 끝점에 메시지를 보내거나 메시지를 부분으로 분할하는 Camel 경로에 적용할 때 예기치 않은 동작이 발생할 수 있습니다. 중간 처리 단계가 원래 메시지를 수정하는 Multicast, Splitter 또는 RecipientList 경로에 원래 메시지가 유지되지 않을 수 있습니다.
Java DSL에서는 교환에서 메시지를 원래 메시지로 교체할 수 있습니다. setAllowUseOriginalMessage()
를 true
로 설정한 다음 다음과 같이 useOriginalMessage()
DSL 명령을 사용합니다.
onException(ValidationException.class) .useOriginalMessage() .to("activemq:validationFailed");
XML DSL에서는 다음과 같이 onException
요소에서 useOriginalMessage
특성을 설정하여 원본 메시지를 검색할 수 있습니다.
<onException useOriginalMessage="true"> <exception>com.mycompany.ValidationException</exception> <to uri="activemq:validationFailed"/> </onException>
setAllowUseOriginalMessage()
옵션이 true
로 설정된 경우 Camel은 경로 시작 시 원본 메시지의 사본을 작성하여 useOriginalMessage()
를 호출할 때 원래 메시지를 사용할 수 있도록 합니다. 그러나 Camel 컨텍스트에서 setAllowUseOriginalMessage()
옵션이 false
(기본값)로 설정된 경우 원래 메시지에 액세스할 수 없으며 useOriginalMessage()
를 호출할 수 없습니다.
기본 동작을 악용하는 이유는 대규모 메시지를 처리할 때 성능을 최적화하는 것입니다.
2.18 이전 Camel 버전에서는 allowUseOriginalMessage
의 기본 설정은 true입니다.
2.3.1.8. Redelivery policy
메시지 처리를 중단하고 예외가 발생하는 즉시 포기하는 대신 Apache Camel은 예외가 발생한 시점에서 메시지를 다시 전달할 수 있는 옵션을 제공합니다. 시간 초과가 발생하고 일시적인 오류가 발생하는 네트워크 시스템에서는 원래 예외가 발생한 직후에 실패한 메시지가 성공적으로 처리될 수 있는 경우가 많습니다.
Apache Camel 재전송은 예외가 발생한 후 메시지를 재전송하기 위한 다양한 전략을 지원합니다. 재전송을 구성하는 가장 중요한 옵션 중 일부는 다음과 같습니다.
maximumRedeliveries()
-
재전송할 수 있는 최대 횟수를 지정합니다(기본값은
0
). 음수 값은 재전송이 항상 시도됨을 의미합니다(무제한 값과 동일). retryWhile()
Apache Camel의 계속 재전송 여부를 결정하는 서술자(예:
Predicate
유형)를 지정합니다. 서술자가 현재 교환에서true
로 평가되면 재전송이 시도됩니다. 그렇지 않으면 재전송이 중지되고 추가 재전송 시도가 수행되지 않습니다.이 옵션은
maximumRedeliveries()
옵션보다 우선합니다.
Java DSL에서 redelivery 정책 옵션은 onException
절의 DSL 명령을 사용하여 지정됩니다. 예를 들어 다음과 같이 교환이 validationFailed
deadletter 큐로 전송되는 최대 6개의 재전송을 지정할 수 있습니다.
onException(ValidationException.class) .maximumRedeliveries(6) .retryAttemptedLogLevel(org.apache.camel.LogginLevel.WARN) .to("activemq:validationFailed");
XML DSL에서 redeliveryPolicy
요소에 속성을 설정하여 재전송 정책 옵션이 지정됩니다. 예를 들어 이전 경로는 다음과 같이 XML DSL로 표시할 수 있습니다.
<onException useOriginalMessage="true"> <exception>com.mycompany.ValidationException</exception> <redeliveryPolicy maximumRedeliveries="6"/> <to uri="activemq:validationFailed"/> </onException>
재전송 옵션은 마지막 재전송 시도가 실패 할 때까지 재전송 옵션이 설정되지 않은 후 경로의 후의 후. 모든 재전송 옵션에 대한 자세한 설명은 6.3절. “dead Letter Channel” 을 참조하십시오.
또는 redeliveryPolicyProfile
인스턴스에서 재전송 정책 옵션을 지정할 수 있습니다. 그런 다음 onException
요소의 redeliverPolicyRef
특성을 사용하여 redeliveryPolicyProfile
인스턴스를 참조할 수 있습니다. 예를 들어 이전 경로는 다음과 같이 표시할 수 있습니다.
<redeliveryPolicyProfile id="redelivPolicy" maximumRedeliveries="6" retryAttemptedLogLevel="WARN"/> <onException useOriginalMessage="true" redeliveryPolicyRef="redelivPolicy"> <exception>com.mycompany.ValidationException</exception> <to uri="activemq:validationFailed"/> </onException>
redeliveryPolicyProfile
을 사용하는 방법은 여러 onException
절에서 동일한 재전송 정책을 다시 사용하려는 경우 유용합니다.
2.3.1.9. 조건부 트래핑
onException
을 사용한 예외 트래핑은 on When
옵션을 지정하여 조건부로 수행할 수 있습니다. onException
절에서 onIf 옵션을 지정하면
throw된 예외가 해당 절 과 일치하고 현재 교환 에서
true
로 평가되는 경우에만 일치가 트리거됩니다.
예를 들어 다음 Java DSL 조각에서 throw된 예외가 MyUserException
과 일치하고 현재 교환에서 사용자
헤더가 null이 아닌 경우에만 첫 번째 onException
절이 트리거됩니다.
// Java // Here we define onException() to catch MyUserException when // there is a header[user] on the exchange that is not null onException(MyUserException.class) .onWhen(header("user").isNotNull()) .maximumRedeliveries(2) .to(ERROR_USER_QUEUE); // Here we define onException to catch MyUserException as a kind // of fallback when the above did not match. // Noitce: The order how we have defined these onException is // important as Camel will resolve in the same order as they // have been defined onException(MyUserException.class) .maximumRedeliveries(2) .to(ERROR_QUEUE);
위의 onException
절은 다음과 같이 XML DSL로 표시할 수 있습니다.
<redeliveryPolicyProfile id="twoRedeliveries" maximumRedeliveries="2"/> <onException redeliveryPolicyRef="twoRedeliveries"> <exception>com.mycompany.MyUserException</exception> <onWhen> <simple>${header.user} != null</simple> </onWhen> <to uri="activemq:error_user_queue"/> </onException> <onException redeliveryPolicyRef="twoRedeliveries"> <exception>com.mycompany.MyUserException</exception> <to uri="activemq:error_queue"/> </onException>
2.3.1.10. 예외 처리
기본적으로 경로 중간에서 예외가 발생하는 경우 현재 교환 처리가 중단되고 경로 시작 시 throw된 예외가 소비자 끝점으로 다시 전파됩니다. onException
절이 트리거되면 throw된 예외가 다시 전파되기 전에 onException
절이 일부 처리를 수행하는 경우를 제외하고 기본적으로 동작이 동일합니다.
그러나 이 기본 동작은 예외를 처리하는 유일한 방법은 아닙니다. onException
은 다음과 같이 예외 처리 동작을 수정하는 다양한 옵션을 제공합니다.
2.3.1.11. 예외 취소 비활성화
현재 예외가 다시 생성되고 소비자 끝점으로 다시 전파되지 않도록 하려면 다음과 같이 Java DSL에서 handled()
옵션을 true
로 설정할 수 있습니다.
onException(ValidationException.class) .handled(true) .to("activemq:validationFailed");
Java DSL에서 handled()
옵션에 대한 인수는 부울 유형, Predicate
유형 또는 Expression
유형 중 하나일 수 있습니다(boolean 이외의 표현식이 null 이외의 값으로 평가되면).
다음과 같이 처리된
요소를 사용하여 XML DSL에서 rethrown 예외를 억제하도록 동일한 경로를 구성할 수 있습니다.
<onException> <exception>com.mycompany.ValidationException</exception> <handled> <constant>true</constant> </handled> <to uri="activemq:validationFailed"/> </onException>
2.3.1.12. 계속 처리
예외가 원래 throw된 경로 지점에서 현재 메시지를 계속 처리하려면 다음과 같이 Java DSL에서 지속적인
옵션을 true
로 설정할 수 있습니다.
onException(ValidationException.class) .continued(true);
Java DSL에서 continued()
옵션에 대한 인수는 부울 유형, Predicate
유형 또는 Expression
유형일 수 있습니다(모든 비boolean 표현식이 true
로 해석되는 경우 null이 아닌 값으로 평가되는 경우).
계속되는
요소를 사용하여 다음과 같이 XML DSL에서 동일한 경로를 구성할 수 있습니다.
<onException> <exception>com.mycompany.ValidationException</exception> <continued> <constant>true</constant> </continued> </onException>
2.3.1.13. 응답 전송
경로를 시작하는 소비자 끝점에 회신이 필요한 경우 throw된 예외가 소비자에게 다시 전파되도록 하는 대신 사용자 정의 오류 응답 메시지를 구성하는 것을 선호할 수 있습니다. 이 경우 수행해야 하는 두 가지 필수 단계가 있습니다. 즉, 처리된
옵션을 사용하여 복구 예외를 표시하지 않고 교환의 Out 메시지 슬롯을 사용자 지정 오류 메시지로 채웁니다.
예를 들어 다음 Java DSL 조각은 MyFunctionalException
예외가 발생할 때마다 텍스트 문자열 Sorry
가 포함된 응답 메시지를 보내는 방법을 보여줍니다.
// we catch MyFunctionalException and want to mark it as handled (= no failure returned to client) // but we want to return a fixed text response, so we transform OUT body as Sorry. onException(MyFunctionalException.class) .handled(true) .transform().constant("Sorry");
클라이언트에 오류 응답을 보내는 경우 응답에 예외 메시지의 텍스트를 통합하려는 경우가 많습니다. exceptionMessage()
builder 메서드를 사용하여 현재 예외 메시지의 텍스트에 액세스할 수 있습니다. 예를 들어 다음과 같이 MyFunctionalException
예외가 발생할 때마다 예외 메시지의 텍스트가 포함된 응답을 보낼 수 있습니다.
// we catch MyFunctionalException and want to mark it as handled (= no failure returned to client) // but we want to return a fixed text response, so we transform OUT body and return the exception message onException(MyFunctionalException.class) .handled(true) .transform(exceptionMessage());
예외 메시지 텍스트는 exception.message
변수를 통해 Simple 언어에서도 액세스할 수 있습니다. 예를 들어 다음과 같이 응답 메시지에 현재 예외 텍스트를 포함할 수 있습니다.
// we catch MyFunctionalException and want to mark it as handled (= no failure returned to client) // but we want to return a fixed text response, so we transform OUT body and return a nice message // using the simple language where we want insert the exception message onException(MyFunctionalException.class) .handled(true) .transform().simple("Error reported: ${exception.message} - cannot process this message.");
위의 onException
절은 다음과 같이 XML DSL로 표현될 수 있습니다.
<onException> <exception>com.mycompany.MyFunctionalException</exception> <handled> <constant>true</constant> </handled> <transform> <simple>Error reported: ${exception.message} - cannot process this message.</simple> </transform> </onException>
2.3.1.14. 예외를 처리하는 동안 throw되는 예외
기존 예외를 처리하는 동안 throw되는 예외(즉, onException 절 처리 중에서 throw되는 예외)는 특별한 방식으로 처리됩니다.An exception that gets thrown while handling an existing exception (in other words, one that gets thrown in the middle of processing an onException
clause) is handled in a special way. 이러한 예외는 다음과 같이 예외를 처리하는 특수 대체 예외 처리기에 의해 처리됩니다.
- 기존 예외 처리기는 모두 무시되고 처리가 즉시 실패합니다.
- 새 예외가 기록됩니다.
- 새로운 예외는 교환 오브젝트에 설정됩니다.
간단한 전략은 onException
절이 무한 루프에 고정되는 상태로 끝날 수 있는 복잡한 실패 시나리오를 방지합니다.
2.3.1.15. 범위
onException
절은 다음 범위 중 하나에서 효과적일 수 있습니다.
RouteBuilder 범위 cidr-
onException
절은RouteBuilder.configure()
메서드 내의 독립 실행형 문으로 정의된 모든RouteBuilder
인스턴스에 정의된 모든 경로에 영향을 미칩니다. 반면, 이러한onException
절은 다른RouteBuilder
인스턴스 내에 정의된 경로에 영향을 미치지 않습니다.onException
절은 경로 정의 앞에 표시되어야 합니다.이 시점까지의 모든 예제는
RouteBuilder
범위를 사용하여 정의됩니다.-
경로 범위 Cryostat-
onException
절을 경로 내에 직접 포함할 수도 있습니다. 이러한 onException 절은 정의된 경로에 만 영향을 미칩니다.
2.3.1.16. 경로 범위
경로 정의 내부에 onException
절을 포함할 수 있지만 end()
DSL 명령을 사용하여 포함된 onException
절을 종료해야 합니다.
예를 들어 다음과 같이 Java DSL에 포함된 onException
절을 정의할 수 있습니다.
// Java from("direct:start") .onException(OrderFailedException.class) .maximumRedeliveries(1) .handled(true) .beanRef("orderService", "orderFailed") .to("mock:error") .end() .beanRef("orderService", "handleOrder") .to("mock:result");
다음과 같이 XML DSL에 포함된 onException
절을 정의할 수 있습니다.
<route errorHandlerRef="deadLetter"> <from uri="direct:start"/> <onException> <exception>com.mycompany.OrderFailedException</exception> <redeliveryPolicy maximumRedeliveries="1"/> <handled> <constant>true</constant> </handled> <bean ref="orderService" method="orderFailed"/> <to uri="mock:error"/> </onException> <bean ref="orderService" method="handleOrder"/> <to uri="mock:result"/> </route>
2.3.2. 오류 처리기
2.3.2.1. 개요
errorHandler()
절은 onException
절과 유사한 기능을 제공합니다. 단, 이 메커니즘은 다른 예외 유형을 구별할 수 없습니다. errorHandler()
절은 Apache Camel에서 제공하는 원래 예외 처리 메커니즘이며 onException
절이 구현되기 전에 사용할 수 있었습니다.
2.3.2.2. Java DSL 예
errorHandler()
절은 RouteBuilder
클래스에 정의되어 있으며 해당 RouteBuilder
클래스의 모든 경로에 적용됩니다. 적용 가능한 경로 중 하나에서 모든 종류의 예외가 발생할 때마다 트리거됩니다. 예를 들어 실패한 모든 교환을 ActiveMQ deadLetter
큐로 라우팅하는 오류 처리기를 정의하려면 다음과 같이 RouteBuilder
를 정의할 수 있습니다.
public class MyRouteBuilder extends RouteBuilder { public void configure() { errorHandler(deadLetterChannel("activemq:deadLetter")); // The preceding error handler applies // to all of the following routes: from("activemq:orderQueue") .to("pop3://fulfillment@acme.com"); from("file:src/data?noop=true") .to("file:target/messages"); // ... } }
그러나 dead letter channel으로의 리디렉션은 다시 전송 시 모든 시도가 소진될 때까지 발생하지 않습니다.
2.3.2.3. XML DSL 예
XML DSL에서는 errorHandler
요소를 사용하여 camelContext
범위 내에 오류 처리기를 정의합니다. 예를 들어 실패한 모든 교환을 ActiveMQ deadLetter
큐로 라우팅하는 오류 처리기를 정의하려면 다음과 같이 errorHandler
요소를 정의할 수 있습니다.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <camelContext xmlns="http://camel.apache.org/schema/spring"> <errorHandler type="DeadLetterChannel" deadLetterUri="activemq:deadLetter"/> <route> <from uri="activemq:orderQueue"/> <to uri="pop3://fulfillment@acme.com"/> </route> <route> <from uri="file:src/data?noop=true"/> <to uri="file:target/messages"/> </route> </camelContext> </beans>
2.3.2.4. 오류 처리기 유형
표 2.1. “오류 처리기 유형” 정의할 수 있는 다양한 유형의 오류 처리기에 대한 개요를 제공합니다.
Java DSL Builder | XML DSL 유형 속성 | 설명 |
---|---|---|
|
| 예외를 호출자로 다시 전파하고 재전송 정책을 지원하지만 dead letter 큐는 지원하지 않습니다. |
|
| 기본 오류 처리기와 동일한 기능을 지원하며, 또한 dead letter 큐를 지원합니다. |
|
| 예외가 발생할 때마다 예외 텍스트를 기록합니다. |
|
| 오류 처리기를 비활성화하는 데 사용할 수 있는 더미 처리기 구현입니다. |
| 트랜잭션된 경로에 대한 오류 처리기입니다. 트랜잭션으로 표시된 경로에 기본 트랜잭션 오류 처리기 인스턴스가 자동으로 사용됩니다. |
2.3.3. DoTry, doCatch 및 doFinally
2.3.3.1. 개요
경로 내에서 예외를 처리하기 위해 doTry
,doCatch
및 doFinally
절을 조합하여 Java의 시도
,catch
, finally
블록과 유사한 방식으로 예외를 처리할 수 있습니다.
2.3.3.2. doCatch와 Java catch 간의 유사점
일반적으로 경로 정의의 doCatch()
절은 Java 코드에서 catch()
문과 유사한 방식으로 작동합니다. 특히 doCatch()
절에서 다음 기능을 지원합니다.
하나의
do Try
블록 내에 여러doCatch
절을 사용할 수 있습니다.doCatch
절은 Javacatch()
문과 마찬가지로 표시되는 순서대로 테스트됩니다. Apache Camel은 throw된 예외와 일치하는 첫 번째doCatch
절을 실행합니다.참고이 알고리즘은
onException
절에서 사용하는 예외 일치 알고리즘과 다릅니다. 자세한 내용은 2.3.1절. “onException Clause” 을 참조하십시오.-
구문을 사용하여
doCatch
절 내에서 현재 예외를 다시 실행할 수 있습니다( “doCatch에서 예외 제거”참조).
2.3.3.3. doCatch의 특수 기능
그러나 Java catch()
문에 유사한 기능이 없는 doCatch()
절의 몇 가지 특수 기능이 있습니다. 다음 기능은 doCatch()
에만 적용됩니다.
-
조건부 수집 Cryostat--->
doCatch
절에on When
하위 복제를 추가하여 조건부로 예외를 catch할 수 있습니다( “on When 사용 중 조건부 예외 catching”참조).
2.3.3.4. 예
다음 예제에서는 Java DSL에 doTry
블록을 작성하는 방법을 보여줍니다. 여기서 doCatch()
절이 실행되는 경우 IOException
예외 또는 IllegalStateException
예외가 발생되고 예외가 발생했는지 여부에 관계없이 doFinally()
절이 항상 실행됩니다.
from("direct:start") .doTry() .process(new ProcessorFail()) .to("mock:result") .doCatch(IOException.class, IllegalStateException.class) .to("mock:catch") .doFinally() .to("mock:finally") .end();
또는 이와 동등한 경우 Spring XML:
<route> <from uri="direct:start"/> <!-- here the try starts. its a try .. catch .. finally just as regular java code --> <doTry> <process ref="processorFail"/> <to uri="mock:result"/> <doCatch> <!-- catch multiple exceptions --> <exception>java.io.IOException</exception> <exception>java.lang.IllegalStateException</exception> <to uri="mock:catch"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route>
2.3.3.5. doCatch에서 예외 제거
다음과 같이 구문을 사용하여 doCatch()
절에서 예외를 다시 시작할 수 있습니다.
from("direct:start") .doTry() .process(new ProcessorFail()) .to("mock:result") .doCatch(IOException.class) .to("mock:io") // Rethrow the exception using a construct instead ofhandled(false)
which is deprecated in adoTry/doCatch
clause. .throwException(new IllegalArgumentException("Forced")) .doCatch(Exception.class) // Catch all other exceptions. .to("mock:error") .end();
doTry/doCatch
절에서 더 이상 사용되지 않는 처리(false)
대신 프로세서를 사용하여 예외를 다시 시작할 수도 있습니다.
.process(exchange -> {throw exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);})
이전 예에서 IOException
이 doCatch()
에 의해 catch되면 현재 교환이 mock:io
엔드포인트로 전송되고 IOException
이 다시 검색됩니다. 이렇게 하면 경로 시작 시 소비자 끝점( from()
명령)도 예외를 처리할 수 있습니다.
다음 예제에서는 Spring XML에서 동일한 경로를 정의하는 방법을 보여줍니다.
<route> <from uri="direct:start"/> <doTry> <process ref="processorFail"/> <to uri="mock:result"/> <doCatch> <to uri="mock:io"/> <throwException message="Forced" exceptionType="java.lang.IllegalArgumentException"/> </doCatch> <doCatch> <!-- Catch all other exceptions. --> <exception>java.lang.Exception</exception> <to uri="mock:error"/> </doCatch> </doTry> </route>
2.3.3.6. on When 사용 중 조건부 예외 catching
Apache Camel doCatch()
절의 특수 기능은 런타임에 평가되는 표현식을 기반으로 예외 catch를 조건부화할 수 있다는 것입니다. 즉, 양식의 절을 사용하여 예외를 catch하는 경우 doCatch(ExceptionList).do When(Expression)
에서는 조건자 표현식, Expression, 런타임 시 true
로 평가되는 경우에만 예외가 catch됩니다.
예를 들어 다음 doTry
블록은 예외인 IOException
및 IllegalStateException
이 예외를 catch합니다. 예외 메시지에 단어 Severe
가 포함된 경우에만 마찬가지입니다.
from("direct:start")
.doTry()
.process(new ProcessorFail())
.to("mock:result")
.doCatch(IOException.class, IllegalStateException.class)
.onWhen(exceptionMessage().contains("Severe"))
.to("mock:catch")
.doCatch(CamelExchangeException.class)
.to("mock:catchCamel")
.doFinally()
.to("mock:finally")
.end();
또는 이와 동등한 경우 Spring XML:
<route> <from uri="direct:start"/> <doTry> <process ref="processorFail"/> <to uri="mock:result"/> <doCatch> <exception>java.io.IOException</exception> <exception>java.lang.IllegalStateException</exception> <onWhen> <simple>${exception.message} contains 'Severe'</simple> </onWhen> <to uri="mock:catch"/> </doCatch> <doCatch> <exception>org.apache.camel.CamelExchangeException</exception> <to uri="mock:catchCamel"/> </doCatch> <doFinally> <to uri="mock:finally"/> </doFinally> </doTry> </route>
2.3.3.7. doTry의 중첩된 조건
JavaDSL 경로에 Camel 예외 처리를 추가하는 데 사용할 수 있는 다양한 옵션이 있습니다. dotry()
는 예외를 처리하기 위한 try 또는 catch 블록을 생성하고 경로별 오류 처리에 유용합니다.
ChoiceDefinition
내에서 예외를 catch하려면 다음 doTry
블록을 사용할 수 있습니다.
from("direct:wayne-get-token").setExchangePattern(ExchangePattern.InOut) .doTry() .to("https4://wayne-token-service") .choice() .when().simple("${header.CamelHttpResponseCode} == '200'") .convertBodyTo(String.class) .setHeader("wayne-token").groovy("body.replaceAll('\"','')") .log(">> Wayne Token : ${header.wayne-token}") .endChoice() .doCatch(java.lang.Class (java.lang.Exception>) .log(">> Exception") .endDoTry(); from("direct:wayne-get-token").setExchangePattern(ExchangePattern.InOut) .doTry() .to("https4://wayne-token-service") .doCatch(Exception.class) .log(">> Exception") .endDoTry();
2.3.4. Cryostat 예외 전파
2.3.4.1. 개요
Camel CXF 구성 요소는 Apache CXF와 통합되므로 Apache Camel 끝점에서 Cryostat 메시지를 보내고 받을 수 있습니다. XML로 Apache Camel 엔드포인트를 쉽게 정의할 수 있으며 엔드포인트의 8080 ID를 사용하여 경로에서 참조할 수 있습니다. 자세한 내용은 Apache Camel 구성 요소 참조 가이드의 CXF 를 참조하십시오.
2.3.4.2. 스택 추적 정보를 전파하는 방법
Java 예외가 서버 측에서 throw될 때 예외에 대한 스택 추적이 오류 메시지로 마샬링되어 클라이언트에 반환되도록 CXF 엔드포인트를 구성할 수 있습니다. 이 페어링을 사용하려면 dataFormat
을 PAYLOAD
로 설정하고 cxfEndpoint
요소에서 faultStackTraceEnabled
속성을 true
로 설정합니다.
<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage" wsdlURL="ship.wsdl" endpointName="s:TestSoapEndpoint" serviceName="s:TestService" xmlns:s="http://test"> <cxf:properties> <!-- enable sending the stack trace back to client; the default value is false--> <entry key="faultStackTraceEnabled" value="true" /> <entry key="dataFormat" value="PAYLOAD" /> </cxf:properties> </cxf:cxfEndpoint>
보안상의 이유로 스택 추적에는 발생 예외가 포함되지 않습니다(즉, 에서 문제를 따르는 스택 추적의 일부). 스택 추적에 발생 예외를 포함하려면 다음과 같이
cxfEndpoint
요소에서 exceptionMessageCauseEnabled
속성을 true
로 설정합니다.
<cxf:cxfEndpoint id="router" address="http://localhost:9002/TestMessage" wsdlURL="ship.wsdl" endpointName="s:TestSoapEndpoint" serviceName="s:TestService" xmlns:s="http://test"> <cxf:properties> <!-- enable to show the cause exception message and the default value is false --> <entry key="exceptionMessageCauseEnabled" value="true" /> <!-- enable to send the stack trace back to client, the default value is false--> <entry key="faultStackTraceEnabled" value="true" /> <entry key="dataFormat" value="PAYLOAD" /> </cxf:properties> </cxf:cxfEndpoint>
테스트 및 진단을 위해 exceptionMessageCauseEnabled
플래그만 활성화해야 합니다. 서버는 적대적인 사용자가 서버를 프로브하는 것을 더 어렵게 만들기 위해 예외의 원래 원인을 숨기는 것이 일반적인 방법입니다.