오류 처리

현재 Apigee Edge 문서가 표시되고 있습니다.
Apigee X 문서로 이동
정보

API 프록시가 앱에서 서비스 요청을 처리하는 동안 많은 오류 조건이 발생할 수 있습니다. 예를 들어 백엔드 서비스와 통신할 때 API 프록시에 네트워크 문제가 발생할 수 있으며, 앱이 만료된 사용자 인증 정보를 표시하거나 요청 메시지의 형식이 잘못되었을 수 있습니다.

클라이언트 앱이 API 프록시를 호출한 후 오류가 발생하면 오류 메시지가 클라이언트에 반환됩니다. 기본적으로 클라이언트는 종종 세부정보나 안내가 없는 암호화 오류 메시지를 수신합니다. 하지만 기본 오류 메시지를 더 유용한 커스텀 메시지로 바꾸고 추가 HTTP 헤더와 같은 내용으로 이를 보강하려면 Edge에서 커스텀 오류 처리를 설정해야 합니다.

커스텀 오류 처리를 사용하면 오류가 발생할 때마다 메시지 로깅과 같은 기능을 추가할 수도 있습니다.

API 프록시에서 커스텀 오류 처리를 구현하는 방법에 대해 논의하기 전에 오류가 어떻게 발생하고 API 프록시가 어떻게 오류에 반응하는지 이해하는 것이 좋습니다.

동영상

오류 처리에 대해 자세히 알아보려면 다음 동영상을 시청하세요.

동영상 설명
오류 처리 및 오류 흐름 소개 오류 처리 및 API 프록시에서 오류가 발생하면 어떻게 되는지 알아봅니다.
오류 규칙을 사용한 오류 처리 오류 규칙을 사용하여 오류를 처리하는 방법을 알아봅니다.
RaiseFault 정책을 사용한 커스텀 오류 발생 RaiseFault 정책을 사용하여 API 런타임 중에 커스텀 오류가 발생합니다.
API 프록시 및 대상 엔드포인트에서 오류 규칙 정의 API 프록시 및 대상 엔드포인트에서 오류 규칙을 정의하고 차이점을 이해합니다.
오류 규칙의 실행 순서 이해 API 프록시 및 대상 엔드포인트에서 오류 규칙의 실행 순서를 이해합니다.
기본 오류 규칙 정의 API에서 일반 오류를 처리하는 기본 오류 규칙을 정의합니다.

오류 발생 방식

우선 오류가 어떻게 발생하는지 간단히 살펴보겠습니다. 오류가 어떻게 발생하는지 알면 커스텀 오류 처리를 구현하려는 다양한 상황을 계획하는 데 도움이 됩니다.

자동 오류

다음과 같은 상황에서 API 프록시에 자동으로 오류가 발생합니다.

  • 정책에서 오류가 발생합니다. 예를 들어 API 호출에서 만료된 키를 전송하면 VerifyAPIKey 정책에서 자동으로 오류가 발생하거나, API 호출 수가 특정 한도를 초과하면 할당량 정책 또는 SpikeArrest 정책에서 오류가 발생합니다. (정책에서 발생할 수 있는 오류 유형은 정책 오류 참조를 확인하세요.)
  • API 프록시 메시지 흐름에 라우팅 오류와 같은 문제가 있습니다.
  • 프로토콜 수준 오류, TLS/SSL 오류 또는 사용할 수 없는 대상 서비스로 인한 HTTP 오류와 같은 백엔드 오류가 있습니다.
  • 메모리 부족 예외와 같은 시스템 수준 오류가 있습니다.

이러한 오류에 대해 자세한 알아보려면 이 주제의 오류 분류를 참조하세요.

커스텀 오류

자동 오류가 없는 경우 커스텀 오류를 발생시킬 수 있는데, 예를 들어 응답에 'unavailable'이라는 단어가 포함되어 있거나 HTTP 상태 코드가 201보다 큰 경우입니다. API 프록시 흐름의 적절한 위치에 RaiseFault 정책을 추가하면 됩니다.

다른 정책과 마찬가지로 RaiseFault 정책을 API 프록시 흐름에 추가할 수 있습니다. 다음 프록시 구성 예시에서는 Raise-Fault-1 정책이 TargetEndpoint 응답에 연결됩니다. 타겟 서비스의 응답에 'unavailable'이라는 단어가 있으면 RaiseFault 정책이 실행되고 오류가 발생합니다.

<TargetEndpoint name="default">
...
  <Response>
    <Step>
      <Name>Raise-Fault-1</Name>
      <Condition>(message.content Like "*unavailable*")</Condition>
    </Step>
  </Response>

이것은 단지 커스텀 오류를 발생시킬 수 있음을 보여주기 위한 것입니다. RaiseFault에 대한 정책은 FaultRules와 RaiseFault 정책 비교 섹션에서 자세히 알아봅니다.

더 많은 예시는 Apigee 커뮤니티 포럼의 다음 게시물을 참조하세요.

오류 발생 시 API 프록시에서 수행하는 작업

프록시에서 오류가 발생하면 다음과 같은 상황이 발생합니다.

프록시 파이프라인 종료

API 프록시에 오류가 발생하면, 발생 방식에 상관없이 정상 흐름 파이프라인이 종료되고 오류 상태가 된 다음 클라이언트 앱에 오류 메시지를 반환합니다. API 프록시가 오류 상태가 되면 정상 흐름 파이프라인으로 돌아가는 처리를 반환할 수 없습니다.

예를 들어 ProxyEndpoint 요청에서 API 프록시에 다음 순서로 정책이 있다고 가정합니다.

  1. API 키 확인
  2. 할당량
  3. JSON에서 XML로 변환

API 키를 확인하는 동안 오류가 발생하면 API 프록시는 오류 상태가 됩니다. 할당량 및 JSON에서 XML로 변환 정책이 실행되지 않고 프록시가 TargetEndpoint로 진행하지 않으면 오류 메시지는 클라이언트 앱으로 반환됩니다.

FaultRule 확인

오류 상태에서 API 프록시는 클라이언트 앱에 기본 오류 메시지를 반환하기 전에 API 프록시 구성에서 다음 항목(순서대로)이 있는지 확인합니다.

  1. 정의한 특정 조건에 따라 커스텀 오류 메시지(및 기타 정책)를 트리거하는 로직이 포함된 <FaultRules> 섹션
  2. 다음 상황에서 기본 오류 메시지를 트리거하는 <DefaultFaultRule> 섹션:
    • <FaultRules>는 정의되지 않습니다.
    • 기존 <FaultRules>가 실행되지 않습니다.
    • <AlwaysEnforce> 요소는 true로 설정됩니다.

기본적으로 API 프록시는 커스텀 오류 메시지를 반환하고 다른 로직을 트리거할 수 있는 기회를 제공합니다. 프록시가 이러한 섹션을 찾지 못했거나 이러한 섹션이 있지만 커스텀 오류가 트리거되지 않은 경우 프록시는 자체 Edge 생성 기본 메시지를 보냅니다.

단순한 오류 처리 예시

API 프록시 호출에 필수 API 키가 포함되지 않은 간단한 예시부터 시작해 보겠습니다. 기본적으로 클라이언트 앱으로 반환되는 응답은 다음과 같습니다.

HTTP/1.1 401 Unauthorized
Date: Wed, 20 Jul 2016 19:19:32 GMT
Content-Type: application/json
Content-Length: 150
Connection: keep-alive
Server: Apigee Router

* Connection #0 to host myorg-test.apigee.net left intact
{"fault":{"faultstring":"Failed to resolve API Key variable request.queryparam.apikey","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}

API 사용자가 오류 메시지를 파악할 수도 있고, 그렇지 않을 수도 있습니다. 또한 많은 기본 오류는 더 미묘하고 해독하기 어렵습니다.

API 개발자가 iOS 앱 개발자든 자체 오류 메시지 형식 요구 사항이 있는 내부 테스트 그룹이든 궁극적으로 오류 메시지를 받게 될 사람의 요구에 맞게 이 메시지를 변경해야 합니다.

다음은 이 오류를 처리하기 위한 커스텀 오류 메시지를 만드는 기본 예시입니다. 이를 위해서는 1) 커스텀 메시지를 정의하는 정책 및 2) 프록시가 오류 상태가 될 때 정책을 실행하는 FaultRule이 필요합니다.

1. 커스텀 메시지를 정의하는 정책을 만듭니다.

먼저 커스텀 오류 메시지를 정의하는 정책을 만듭니다. 상태 코드 및 이유 구문과 같은 선택적 HTTP 헤더와 페이로드를 설정할 수 있는 AssignMessage 정책과 같이 모든 유형의 정책을 사용할 수 있습니다. 메시지 할당이 여기에 적합합니다. 이를 통해 메시지 페이로드를 제어하고, 다른 HTTP 상태 코드를 설정하고, 다른 HTTP 이유 구문을 설정하고, HTTP 헤더를 추가할 수 있습니다.

API 프록시의 어떠한 흐름에도 정책을 연결하지 마십시오. 프록시 번들에 존재하는 것으로 충분합니다. 관리 UI 프록시 편집기에서 이렇게 하려면 개발 탭으로 이동한 다음 탐색창에서 정책 표시줄의 + 아이콘을 클릭합니다.

이렇게 하면 API 프록시 흐름에 연결하지 않고도 정책을 만들 수 있습니다. 흐름에 연결되지 않은 정책은 앞의 그림에 표시된 API 키 메시지 정책에 인접한 정책 목록에서 '분리된' 아이콘으로 표시됩니다.

다음은 AssignMessage 정책의 예시입니다.

  • JSON 메시지를 반환합니다.
  • 유연성을 보여주기 위해 HTTP 상태 코드 (911, 존재하지 않는 명백한 상태 코드)를 설정합니다. 상태 코드는 HTTP 헤더에 표시됩니다.
  • HTTP 이유 구문(누락된 API 키 오류에 대한 기본 '승인되지 않은' 이유 구문을 대체하기 위한)을 설정합니다. HTTP 헤더의 상태 코드 옆에 이유 구문이 표시됩니다.
  • invalidKey라는 새 HTTP 헤더를 만들고 채웁니다.
<AssignMessage async="false" continueOnError="false" enabled="true" name="invalid-key-message">
    <DisplayName>Invalid key message</DisplayName>
    <Set>
        <Payload contentType="application/json">{"Citizen":"Where's your API key? I don't see it as a query parameter"}</Payload>
        <StatusCode>911</StatusCode>
        <ReasonPhrase>Rejected by API Key Emergency Services</ReasonPhrase>
    </Set>
    <Add>
        <Headers>
            <Header name="invalidKey">Invalid API key! Call the cops!</Header>
        </Headers>
    </Add>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="request"/>
</AssignMessage>

이 정책이 실행되면 클라이언트 앱에 대한 응답이 다음과 같이 표시됩니다. 이전에 표시된 기본 응답과 비교합니다.

HTTP/1.1 911 Rejected by API Key Emergency Services
Date: Wed, 20 Jul 2016 18:42:36 GMT
Content-Type: application/json
Content-Length: 35
Connection: keep-alive
invalidKey: Invalid API key! Call the cops!
Server: Apigee Router

* Connection #0 to host myorg-test.apigee.net left intact
{"Citizen":"Where's your API key? I don't see it as a query parameter."}

예, 약간 어리석지만 가능한 것을 보여줍니다. 이제 메시지를 받은 개발자는 API 키를 쿼리 매개변수로 포함하지 않았다는 것을 알고 있습니다.

이 정책은 어떻게 실행되나요? 다음 섹션에서는 이를 보여줍니다.

2. 정책을 트리거할 <FaultRule>을 만듭니다.

프록시 구성의 <ProxyEndpoint> 또는 <TargetEndpoint> 섹션에서 하나 이상의 개별 <FaultRule> 섹션을 포함하는 <FaultRules> XML 블록을 추가합니다. 각 FaultRule은 처리하려는 다른 오류를 나타냅니다. 이 간단한 예시에서는 구성요소를 보여주기 위해 FaultRule을 하나만 사용합니다.

또한 <DefaultFaultRule>을 추가하여 FaultRule이 실행되지 않은 경우 커스텀 일반 오류 메시지를 제공해야 합니다.

<ProxyEndpoint name="default">
...
    <FaultRules>
       <FaultRule name="invalid_key_rule">
            <Step>
                <Name>invalid-key-message</Name>
            </Step>
            <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
        </FaultRule>
    </FaultRules>
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

핵심 사항:

  • FaultRule은 ProxyEndpoint에 정의되어 있습니다. 이 점은 중요합니다. 이후에 ProxyEndpoint와 TargetEndpoint 비교에서 FaultRules를 추가하는 방법에 대해 자세히 알아보세요.
  • <Name> - 실행할 정책의 이름입니다. 이름은 이전 정책 예시에 표시된 것처럼 상위 요소에 있는 정책의 name 속성에서 가져옵니다.
  • <Condition> - Edge가 조건을 평가하고 조건이 참인 경우에만 정책을 실행합니다. true로 판정된 FaultRules가 여러 개 있으면 Edge는 true인 첫 번째 FaultRules를 실행합니다. (중요: 여러 FaultRule 및 실행 로직 섹션에 설명된 대로 FaultRule이 평가되는 순서(위에서 아래로 또는 아래에서 위로)는 TargetEndpoint와 ProxyEndpoint 간에 다릅니다. 조건을 포함하지 않으면 FaultRule이 자동으로 true가 됩니다. 하지만 이는 권장사항이 아닙니다. FaultRule마다 고유한 조건이 있어야 합니다.

  • <DefaultFaultRule> - 커스텀 FaultRule이 실행되지 않으면 <DefaultFaultRule>가 실행되어 암호화된 기본 Edge 생성 메시지 대신 더 일반적인 커스텀 메시지를 전송합니다. <DefaultFaultRule>에는 <Condition>도 포함될 수 있지만 대부분의 경우 마지막 수단으로 실행하려 하므로 포함하지 않습니다.

    DefaultFaultRule은 일반적으로 예상치 못한 오류에 대한 일반 오류 메시지를 반환하는 데 사용됩니다. 기술 지원에 대한 연락처 정보가 포함된 메시지를 예시로 들 수 있습니다. 이 기본 응답은 개발자에게 친숙한 정보를 제공하는 동시에 시스템을 손상시키는 데 사용될 수 있는 백엔드 URL 또는 기타 정보를 난독화하는 두 가지 용도로 사용됩니다.

여러 FaultRule 및 실행 로직

간단한 오류 처리 예시 섹션에서는 단일 FaultRule 및 조건의 간단한 예시를 사용했습니다. 실제 API 프로젝트에서는 발생할 수 있는 모든 오류를 포함하여 <ProxyEndpoint><TargetEndpoint>에 여러 FaultRule과 DefaultFaultRule이 있을 수 있습니다. 그러나 궁극적으로 API 프록시가 오류 상태가 되면 하나의 FaultRule만 실행됩니다.

이 섹션에서는 실행을 위해 단일 FaultRule에 도달하는 방법부터 FaultRule이 트리거될 때 '내부' 단계 조건이 처리되는 방법에 이르기까지 Edge가 FaultRules를 처리할 때 사용하는 로직을 설명합니다. 또한 이 섹션에서는 <ProxyEndpoint><TargetEndpoint> 비교에서 FaultRules를 정의해야 하는 경우에 대한 지침을 제공하며, FaultRules와 RaiseFault 정책의 관계를 설명합니다.

FaultRules 실행

다음은 API 프록시가 오류 상태로 전환될 때 Edge에서 사용하는 로직입니다. ProxyEndpoint와 TargetEndpoint의 비교에서 FaultRule 평가 사이에는 약간의 차이가 있습니다.

  1. Edge는 오류가 발생한 위치에 따라 ProxyEndpoint 또는 TargetEndpoint에서 FaultRules를 평가합니다.
    • ProxyEndpoint - Edge는 구성 XML에서 하단 <FaultRule>로 시작하여 위로 올라가 각 <FaultRule><Condition>('내부' <Step> 조건이 아닌 '외부' 조건)를 평가합니다.
    • TargetEndpoint - Edge가 구성 XML에서 최상위 <FaultRule>로 시작하여 하향식으로 각 <FaultRule><Condition>('내부' <Step> 조건이 아닌 '외부' 조건)를 평가합니다.
  2. 조건이 true인 첫 번째 FaultRule을 실행합니다. FaultRule에 조건이 없는 경우 기본적으로 true입니다.
    • FaultRule이 실행되면 FaultRule 내부의 모든 단계가 XML 구성의 위에서 아래로 순서대로 평가됩니다. 조건이 없는 단계는 자동으로 실행되고(정책 실행), 'true'로 평가되는 <Condition>이 있는 단계가 실행됩니다('false'로 평가되는 조건은 실행되지 않음).
    • FaultRule이 실행되었지만 FaultRule의 단계가 실행되지 않으면 (조건이 'false'로 평가되어) Edge에서 생성된 기본 오류 메시지가 클라이언트 앱으로 반환됩니다. Edge가 이미 하나의 FaultRule을 실행했으므로 <DefaultFaultRule>는 실행되지 않습니다.

  3. FaultRule이 실행되지 않으면 Edge는 <DefaultFaultRule>을 실행합니다(있는 경우).

다음은 인라인 주석이 있는 예시입니다.

ProxyEndpoint 실행

ProxyEndpoint FaultRule의 평가는 아래에서 위로 진행되므로 다음 샘플의 마지막 FaultRule에서 읽기를 시작하고 계속해서 위로 진행하십시오. DefaultFaultRule을 마지막으로 확인합니다.

<ProxyEndpoint name="default">
...
    <FaultRules>
<!-- 3. This FaultRule is automatically TRUE, because there's no "outer" 
     condition. But because the FaultRule just below this got
     executed (bottom-to-top evaluation in a ProxyEndpoint), Edge
     doesn't even evaluate this FaultRule.
     Note that it's not a best practice to have a FaultRule without 
     an outer condition, which automatically makes the FaultRule true. -->
        <FaultRule name="random-error-message">
            <Step>
                <Name>Random-fault</Name>
            </Step>
        </FaultRule>
<!-- 2. Let's say this fault is TRUE. The Quota policy threw a QuotaViolation
     error. This is the first FaultRule to be TRUE, so it's executed. 
     Now the Steps are evaluated, and for the ones whose conditions
     evaluate to TRUE, their policies are executed. Steps without
     conditions are automatically true. -->
<FaultRule name="over_quota">
            <Step>
                <Name>developer-over-quota-fault</Name>
                <Condition>(ratelimit.developer-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>global-over-quota-fault</Name>
                <Condition>(ratelimit.global-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>log-error-message</Name>
            </Step>
            <Condition>(fault.name = "QuotaViolation")</Condition>
        </FaultRule>
<!-- 1. Because this is the ProxyEndpoint, Edge looks at this FaultRule
     first. But let's say this FaultRule is FALSE. A policy did not 
     throw a FailedToResolveAPIKey error. Edge moves UP to check
     the next FaultRule. -->
        <FaultRule name="invalid_key_rule">
            <Step>
                <Name>invalid-key-message</Name>
            </Step>
            <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
        </FaultRule>
    </FaultRules>

<!-- If no <FaultRule> is executed, the <DefaultFaultRule> is executed. 
     If a FaultRule is executed, but none of its Steps are executed,
     The DefaultFaultRule is not executed (because Edge has already
     executed its one FaultRule). -->
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

TargetEndpoint 실행

TargetEndpoint FaultRule의 평가는 위에서 아래로 진행되므로 다음 샘플의 첫 번째 FaultRule에서 읽기를 시작하고 계속해서 아래로 진행하십시오. DefaultFaultRule을 마지막으로 확인합니다.

<TargetEndpoint name="default">
...
    <FaultRules>
<!-- 1. Because this is the TargetEndpoint, Edge looks at this FaultRule
     first. Let's say this FaultRule is FALSE. 
     A policy did not throw a FailedToResolveAPIKey error. 
     Edge moves down to the next FaultRule. -->
        <FaultRule name="invalid_key_rule">
            <Step>
                <Name>invalid-key-message</Name>
            </Step>
            <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
        </FaultRule>
<!-- 2. Let's say this fault is TRUE. The Quota policy threw a QuotaViolation
     error. This is the first FaultRule to be TRUE, so it's executed. 
     Now the Steps are evaluated, and for the ones whose conditions
     evaluate to TRUE, their policies are executed. Steps without
     conditions are automatically true. -->
        <FaultRule name="over_quota">
            <Step>
                <Name>developer-over-quota-fault</Name>
                <Condition>(ratelimit.developer-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>global-over-quota-fault</Name>
                <Condition>(ratelimit.global-quota-policy.exceed.count GreaterThan "0")</Condition>
            </Step>
            <Step>
                <Name>log-error-message</Name>
            </Step>
            <Condition>(fault.name = "QuotaViolation")</Condition>
        </FaultRule>
<!-- 3. This FaultRule is automatically TRUE, because there's no "outer" 
     condition. But because the FaultRule just above this got
     executed (top-to-bottom evaluation in a TargetEndpoint), Edge
     doesn't even evaluate this FaultRule.
     Note that it's not a best practice to have a FaultRule without 
     an outer condition, which automatically makes the FaultRule true. -->
        <FaultRule name="random-error-message">
            <Step>
                <Name>Random-fault</Name>
            </Step>
        </FaultRule>
    </FaultRules>

<!-- If no <FaultRule> is executed, the <DefaultFaultRule> is executed. 
     If a FaultRule is executed, but none of its Steps are executed,
     The DefaultFaultRule is not executed (because Edge has already
     executed its one FaultRule). -->
    <DefaultFaultRule name="default-fault">
        <Step>
            <Name>Default-message</Name>
        </Step>
    </DefaultFaultRule>

오류 규칙 순서

이전 예시에서 볼 수 있듯이 FaultRule 배치는 오류가 ProxyEndpoint와 TargetEndpoint 중 어디에서 발생했는지 여부가 중요합니다.

예를 들면 다음과 같습니다.

ProxyEndpoint 순서 TargetEndpoint 순서

다음 예시에서는 평가가 아래에서 위로 진행되므로 FaultRule 3이 실행됩니다. 즉, FaultRule 2와 1은 평가되지 않습니다.

5. FaultRule 1: FALSE

4. FaultRule 2: TRUE

3. FaultRule 3: TRUE

2. FaultRule 4: FALSE

1. FaultRule: 5 FALSE

다음 예시에서는 평가가 위에서 아래로 진행되므로 FaultRule 2가 실행됩니다. 즉, FaultRule 3, 4, 5는 평가되지 않습니다.

1. FaultRule 1: FALSE

2. FaultRule 2: TRUE

3. FaultRule 3: TRUE

4. FaultRule 4: FALSE

5. FaultRule: 5 FALSE

포함할 정책

FaultRule에서 모든 정책을 단계에 배치하여 실행할 수 있습니다. 예를 들어 AssignMessage 정책을 실행하여 클라이언트 앱에 대한 응답 형식을 지정한 후 MessageLogging 정책으로 메시지를 로깅할 수 있습니다. 정책은 배치된 순서로 실행됩니다(XML에서 위에서 아래로).

오류 규칙은 오류 상태에서만 트리거됩니다 (ContinueOnError 정보).

제목이 반복된 것처럼 보일 수 있지만 API 프록시가 오류 상태가 되는 경우 또는 오류 상태가 되지 않는 경우(정책의 continueOnError 속성) 프록시 오류의 미묘한 차이에 유의해야 합니다.

요약: API 프록시는 프록시가 오류 상태에 도달한 경우에 <FaultRules><DefaultFaultRule>을 평가합니다. 즉, FaultRule 조건이 true로 평가되더라도 프록시가 오류 상태가 아니면 트리거되지 않습니다.

다음은 오류가 발생하고 프록시가 오류 상태가 되지 않는 예시입니다. 모든 정책에서 continueOnError라는 상위 요소에 속성을 설정할 수 있습니다. 이 속성은 정책이 실패할 경우 프록시가 오류 상태가 되는지 여부를 판단하므로 오류 처리 과정에서 매우 중요합니다. 대부분의 경우 정책이 실패할 경우 프록시를 오류 상태가 되고 커스텀 오류 처리가 트리거되는 기본 continueOnError="false"를 유지하는 것이 좋습니다. 그러나 continueOnError="true"인 경우(예를 들어 서비스 콜아웃 장애 시 프록시 실행이 중지되지 않도록 하려는 경우) 정책이 실패해도 프록시가 오류 상태가 되지 않으며 프록시에서 FaultRule을 확인하지 않습니다.

continueOnError="true" 로깅 오류에 대해 자세히 알아보려면 현재 흐름 내에서 정책 오류 처리를 참조하세요.

FaultRule을 정의할 위치: ProxyEndpoint 또는 TargetEndpoint

API 프록시에 오류가 발생하면 <ProxyEndpoint>(클라이언트 앱에 대한 요청 또는 응답) 또는 <TargetEndpoint>(대상 서비스에 대한 요청 또는 응답)에서 오류가 발생합니다. 이 오류가 발생할 때마다 Edge는 FaultRules를 찾습니다.

예를 들어 대상 서버를 사용할 수 없는 경우(HTTP 상태 코드 503) API 프록시가 <TargetEndpoint> 응답에서 오류 상태로 전환되고 일반 API 프록시 흐름이 <ProxyEndpoint>로 진행되지 않습니다. <ProxyEndpoint>에만 정의된 FaultRules가 있는 경우 해당 오류는 처리되지 않습니다.

예를 들면 다음과 같습니다. <ProxyEndpoint> 응답의 RaiseFault 정책에서 오류를 트리거하면 <TargetEndpoint>에서 FaultRule이 실행되지 않습니다.

FaultRules와 RaiseFault 정책 비교

오류 규칙과 RaiseFault 정책은 표면적으로 오류 처리를 수행하는 다른 방법처럼 들릴 수 있으며, 어떤 면에서 그것은 사실입니다. 하지만 이 두 요소 역시 함께 작동합니다. 이 섹션에서는 이 둘의 관계를 설명합니다. 이 관계를 이해하면, 특히 둘 다 사용하려는 경우 오류 처리를 설계하는 데 도움이 됩니다.

간단히 말하면 다음과 같습니다.

  • 오류 규칙은 API 프록시가 오류 상태가 될 때 항상 평가됩니다.
  • RaiseFault 정책은 오류가 발생하지 않았을 때 API 프록시를 오류 상태로 만드는 방법입니다.

    예를 들어 대상 서비스의 응답에 있는 HTTP 상태 코드가 200보다 큰 경우 오류를 발생시키려면 응답 흐름에 RaiseFault 정책을 추가합니다. URL에 태그를 추가하는 방법은 다음과 같습니다.

    <TargetEndpoint name="default">
        <PreFlow name="PreFlow">
    ...
            <Response>
                <Step>
                    <Name>Raise-Fault-1</Name>
    <!-- If the condition is true, the Raise-Fault-1 policy gets executed -->
                    <Condition>(response.status.code GreaterThan "200")</Condition>
                </Step>
            </Response> 
    

    RaiseFault 정책은 클라이언트 앱에도 오류 메시지를 보냅니다.

RaiseFault 정책이 오류를 트리거하여 프록시를 오류 상태로 만들고, 잠재적으로 FaultRule을 실행하면 어떻게 될까요? 여기에서 약간의 문제가 발생할 수 있습니다. RaiseFault 정책에서 오류 메시지가 반환되고, FaultRule이 트리거되며 오류 메시지가 반환되는 경우 클라이언트 앱으로 반환되는 항목은 무엇인가요?

  • RaiseFault 정책 다음에 FaultRule 또는 DefaultFaultRule이 실행되므로 FaultRule 응답 데이터가 우선합니다.
  • RaiseFault 정책 응답 데이터(상태 코드, 이유 구문, 메시지 페이로드)는 해당 데이터가 FaultRule 또는 DefaultFaultRule에 의해 설정되지 않은 경우에 사용됩니다.
  • RaiseFault 정책과 FaultRule 모두 커스텀 HTTP 헤더를 추가하면 둘 다 응답에 포함됩니다. 중복된 헤더 이름은 여러 값이 있는 헤더를 만듭니다.

다음은 RaiseFault 정책 및 FaultRule에서 설정한 항목과 클라이언트 앱으로 반환되는 항목의 예시입니다. 이 샘플은 권장사항이 아닌 간결성을 위해 설계되었습니다.

클라이언트 앱에서 수신:

Status Code: 468
Reason Phrase: Something happened
Payload: {"Whoa":"Sorry."}
Header: 
  errorNote: woops,gremlins

<- 오류 규칙 정책에서 다음 설정:

Status Code: [none] 
Reason Phrase: Something happened
Payload: {"Whoa":"Sorry."}
Header: 
  errorNote: gremlins

<- RaiseFault 정책에서 다음 설정:

Status Code: 468
Reason Phrase: Can't do that
Payload: {"DOH!":"Try again."}
Header: 
  errorNote: woops

조건 작성

조건은 FaultRule 실행의 핵심입니다. 조건부 흐름 또는 RaiseFault 조건과 같은 Edge의 다른 조건에 대해 수행하는 것과 동일한 방식으로 FaultRule 조건을 만듭니다.

이 섹션의 나머지 부분을 이해할 수 있도록 외부 FaultRule 조건과 내부 단계 조건이 있는 샘플 오류 규칙을 예시로 들어 보겠습니다.

<FaultRule name="invalid_key_rule">
    <Step>
        <Name>invalid-key-message</Name>
        <Condition>(oauthV2.Verify-API-Key-1.failed = true)</Condition>
    </Step>
    <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
</FaultRule>

정책 오류 관련 변수

fault.name{policy_namespace}.{policy_name}.failed 변수는 정책에서 오류가 발생할 때 사용할 수 있습니다.

fault.name

정책이 실패하면 fault.name 변수를 사용하여 조건의 오류를 파악합니다. 예를 들면 다음과 같습니다.

<Condition>(fault.name = "policy_error_name")</Condition>

기본 오류 메시지에 오류 이름이 표시됩니다. 예를 들어 다음에서 오류 이름은 FailedToResolveAPIKey입니다. 이 경우 fault.name이라는 흐름 변수는 FailedToResolveAPIKey 값으로 설정됩니다.

{"fault":{"faultstring":"Failed to resolve API Key variable request.queryparam.apikey","detail":{"errorcode":"steps.oauth.v2.FailedToResolveAPIKey"}}}

따라서 조건은 다음과 같습니다.

<Condition>(fault.name = "FailedToResolveAPIKey")</Condition>

정책 오류 목록은 정책 오류 참조를 참고하세요.

{policy_namespace}.{policy_name}.failed

*.failed 변수는 정책이 실패할 때 사용할 수 있습니다. 다음은 다른 정책의 *.failed 변수 예시입니다. 정책 네임스페이스는 각 정책 참조 주제의 흐름 변수를 참조하세요.

기타 사용 가능한 변수

API 프록시가 오류 상태가 되면 조건에 사용할 수 있는 유일한 변수는 다음과 같습니다.

  • 실패한 정책 변수입니다.
  • 오류 시점에 존재하는 HTTP 메시지 변수입니다. 예를 들어 응답에서 오류가 발생하면 <TargetEndpoint>의 FaultRule이 HTTP 데이터 response.status.code, message.content, error.content 등을 사용할 수 있습니다. 또는 할당량 정책이 실패하면 ratelimit.{quota_policy_name}.exceed.count 변수를 사용할 수 있습니다. Trace 도구정책 참조 주제를 통해 사용할 수 있는 변수와 HTTP 데이터를 확인하세요.

추가 정보

  • 조건: 조건 참조흐름 변수 및 조건

  • 오류: 정책 오류 참조
  • 변수: 변수 참조. 각 정책에서 사용 가능한 변수의 개별 정책 참조 페이지를 확인하세요.

오류 처리 권장사항

팁: 오류 처리는 API 프록시 개발을 위한 주요 아키텍처 설계 작업입니다. 시간을 내어 언제 어떻게 오류를 처리할지, 어떤 오류 메시지를 표시할지 결정하고 오류 메시지 형식을 설계합니다. 이러한 사항을 파악할 때 또는 파악한 후 다음 권장사항을 사용하면 오류 처리 구현에 도움이 됩니다.

오류 처리를 설계하고 빌드할 때는 사용할 수 있는 몇 가지 권장사항은 다음과 같습니다.

  • 각 FaultRule에 <Step> 요소의 동위인 '외부' <Condition>를 제공합니다. 외부 조건이 없는 오류 규칙은 자동으로 true로 평가됩니다. '내부' 단계 조건은 FaultRule이 true인지 false인지 확인하는 데 사용되지 않습니다. 단계 조건은 Edge가 단계 조건을 포함하는 FaultRule을 실행한 후에만 평가됩니다. FaultRule에서는 일반적으로 메시지 할당 (또는 기타) 정책이 포함된 여러 단계가 있으며 각 단계에는 단계 조건이 있습니다.
  • 동일한 유형의 여러 정책(예: 여러 할당량 정책)에서 오류를 처리하려면 수신할 수 있는 정책 오류당 FaultRule을 하나씩 만드세요. 예를 들어 QuotaViolation, InvalidMessageWeight, StartTimeNotSupported와 같은 할당량 정책의 각 오류에 대한 FaultRule을 만듭니다. 정책 오류는 정책 오류 참조를 확인하세요. 처리해야 할 추가 오류가 발견되면 나중에 돌아가서 FaultRule에 오류를 추가할 수 있습니다. 프록시 재배포가 필요하지만 반복될 수 있습니다. 이 방식을 사용하면 어떤 정책에서 발생하든 상관없이 동일한 유형의 오류를 포착할 수 있으므로 FaultRule XML을 효율적으로 만들 수 있습니다.

    보다 세분화된 오류 제어가 필요한 경우 내부 단계 조건을 사용합니다. 예를 들어 요청 흐름에 두 개의 정책을 사용하여 개별 개발자 할당량과 전역 할당량을 모두 적용하는 경우 QuotaViolation 오류 (두 경우 모두 할당량이 초과될 때 발생)에서 트리거되도록 '외부' FaultRule 조건을 설정합니다. 그런 다음 두 할당량 정책 모두에서 exceed.count 변수를 평가하도록 단계 조건을 설정합니다. 관련 오류만 클라이언트로 전송됩니다(개발자 할당량 초과 또는 글로벌 할당량 초과). 이 구성의 예시는 다음과 같습니다.

    <FaultRule name="over_quota">
    <!-- This condition catches a QuotaViolation in *any* Quota policy -->
      <Condition>(fault.name = "QuotaViolation")</Condition>
      <Step>
        <Name>developer-over-quota-fault</Name>
        <Condition>(ratelimit.developer-quota-policy.exceed.count GreaterThan "0")</Condition>
      </Step>
      <Step>
        <Name>global-over-quota-fault</Name>
        <Condition>(ratelimit.global-quota-policy.exceed.count GreaterThan "0")</Condition>
      </Step>
    </FaultRule>
    

    다른 예시는 Apigee 커뮤니티 스레드를 참조하세요.

  • 한 가지 유형의 단일 정책을 사용하는 경우 오류를 처리하려면 하나의 정책이 실패할 때 실행되는 단일 오류 규칙을 고려하고 가능한 각 오류에 매핑되는 여러 단계를 포함합니다. 이렇게 하면 여러 FaultRule(각 오류 유형당 하나)이 아닌 단일 FaultRule을 사용하여 XML을 효율적으로 유지할 수 있습니다. 예를 들면 다음과 같습니다.

    <FaultRule name="raise-fault-3">
    <!-- This condition catches *any* error in the Verify-API-Key-1 policy. -->
      <Condition>(oauthV2.Verify-API-Key-1.failed = "true")</Condition>
      <!-- This first step always executes, which handles errors you haven't mapped with inner conditions. -->
      <Step>
        <Name>Generic-Key-Fault</Name>
      </Step>
      <Step>
        <Name>Assign-Message-Raise-Fault-1</Name>
        <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
      </Step>
      <Step>
        <Name>Assign-Message-Raise-Fault-2</Name>
        <Condition>(fault.name = "InvalidApiKey")</Condition>
      </Step>
    </FaultRule>
    
  • 오류가 발생한 FaultRule을 추가합니다(클라이언트 측 <ProxyEndpoint> 또는 대상 측 <TargetEndpoint>). 각 위치에 나타나는 각 정책에 대한 FaultRule을 포함합니다.
  • FaultRule에서 클라이언트 앱에 메시지를 반환할 수 있는 모든 유형의 정책을 실행할 수 있습니다. 이 경우 AssignMessage 정책이 적합합니다. 또한 계속해서 오류를 추적하려면 MessageLogging 정책이 있는 메시지를 로깅하는 것이 좋습니다.
  • FaultRule과 함께 RaiseFault 정책을 사용하는 경우, RaiseFault 정책과 FaultRule 데이터가 모두 반환될 때 전송되는 응답 데이터를 조정합니다. 예를 들어 RaiseFault 정책이 HTTP 상태 코드를 재설정하는 경우 FaultRule은 상태 코드를 재설정하지 마세요. 발생할 수 있는 최악의 경우는 기본 상태 코드가 클라이언트 앱으로 반환되는 것입니다.
  • <DefaultFaultRule> 실행:
    • <DefaultFaultRule>이 다른 FaultRule이 실행되지 않을 때 항상 실행되도록 하려면 <Condition>을 클릭합니다.
    • 다른 FaultRule이 실행된 경우에도 <DefaultFaultRule>이 항상 실행되도록 하려면 <AlwaysEnforce>true</AlwaysEnforce> 하위 요소를 추가하세요.

재사용 가능한 중앙 집중식 오류 처리를 위한 패턴

다음 Apigee 커뮤니티 게시물에서는 코드 중복 없이 중앙 집중식 오류 처리를 위한 패턴을 설명합니다.

https://community.apigee.com/articles/23724/an-error-handling-pattern-for-apigee-proxies.html

FaultRules 만들기

FaultRule을 추가하려면 ProxyEndpoint 또는 TargetEndpoint의 XML 구성을 수정해야 합니다. Edge UI를 사용하여 API 프록시의 Develop 뷰에 있는 Code 창에서 수정하거나 ProxyEndpoint 또는 TargetEndpoint를 정의하는 XML 파일을 수정할 수 있습니다.

관리 UI에서 FaultRules를 만드는 경우 먼저 실행할 정책을 만든 후 FaultRule 구성에 추가합니다. (아직 생성되지 않은 정책을 참조하는 FaultRule을 저장하려 하면 UI에 오류가 표시됩니다.)

FaultRule에 정책 추가

FaultRule에 모든 정책을 포함할 수 있지만 일반적으로 AssignMessage 정책을 사용하여 오류 조건에 대한 커스텀 응답 메시지를 생성합니다. AssignMessage를 사용 설정하면 페이로드, HTTP 상태 코드, 헤더, 이유 구문 요소로 HTTP 응답을 구성할 수 있습니다.

아래 예시에서는 일반적인 AssignMessage 정책 구성을 보여줍니다.

<AssignMessage name="fault_invalidkey">
  <Set>
      <Payload contentType="text/plain">Contact support at support@mycompany.com.</Payload>
      <StatusCode>401</StatusCode>
      <ReasonPhrase>Unauthorized</ReasonPhrase>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

이제 FaultRule에서 이 정책을 사용할 수 있습니다. FaultRule에서 이름을 기준으로 AssignMessage 정책을 참조하는 방법을 확인하세요.

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>fault_invalidkey</Name>
      </Step>
      <Condition>(fault.name = "InvalidApiKey")</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

위 구성을 배포하면 API 프록시는 앱에 잘못된 API 키가 있을 때마다 fault_invalidkey라는 AssignMessage 정책을 실행합니다.

다음 예시에 표시된 대로 FaultRule에서 여러 정책을 실행할 수 있습니다.

<ProxyEndpoint name="default">
  ...
  <FaultRules>
    <FaultRule name="invalid_key_rule">
      <Step>
        <Name>policy1</Name>
      </Step>
      <Step>
        <Name>policy2</Name>
      </Step>
      <Step>
        <Name>policy3</Name>
      </Step>
      <Condition>(fault.name = "InvalidApiKey")</Condition>
    </FaultRule>
  </FaultRules>
</ProxyEndpoint>

이 정책은 정의된 순서대로 실행됩니다. 예를 들어 MessageLogging 정책, ExtractVariables 정책, AssignMessage 정책 또는 FaultRule의 모든 기타 정책을 사용할 수 있습니다. 다음 상황 중 하나가 발생하면 FaultRule 처리가 즉시 중지됩니다.

  • 오류가 발생하는 모든 FaultRule 정책
  • FaultRule의 모든 정책은 RaiseFault 유형입니다.

FaultRule에서 반환된 커스텀 오류 메시지 정의

API의 명확한 오류 응답을 정의하는 것이 좋습니다. 이렇게 하면 클라이언트에게 일관되고 유용한 정보를 전달할 수 있습니다.

다음 AssignMessage 정책 예시에서는 <Payload>, <StatusCode>, <ReasonPhase> 태그를 사용하여 InvalidApiKey 오류에 대해 클라이언트로 다시 전송되는 커스텀 오류 응답을 정의합니다(이전 FaultRule 예시 참조).

<AssignMessage name="fault_invalidkey">
  <Set>
    <Payload contentType="text/plain">You have attempted to access a resource without the correct authorization. 
       Contact support at support@mycompany.com.</Payload>
    <StatusCode>401</StatusCode>
    <ReasonPhrase>Unauthorized</ReasonPhrase>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

이 응답에는 다음이 포함됩니다.

  • 오류 메시지 및 지원팀에 문의할 수 있는 이메일 주소가 포함된 페이로드입니다.
  • 응답에서 반환된 HTTP 상태 코드입니다.
  • 오류에 대한 간단한 설명 이유 구문입니다.

DefaultFaultRule 만들기

DefaultFaultRule이 다른 FaultRule에서 명시적으로 처리하지 않는 오류에 대해 예외 핸들러 역할을 수행합니다. 모든 FaultRules 조건이 오류와 일치하지 않으면 DefaultFaultRule에서 오류를 처리합니다. <DefaultFaultRule> 태그를 ProxyEndpoint 또는 TargetEndpoint의 하위 요소로 추가하여 기본 오류 처리를 사용 설정합니다.

예를 들어 아래의 TargetEndpoint 구성은 ReturnGenericError라는 정책을 호출하는 DefaultFaultRule을 정의합니다.

<TargetEndpoint name="default">
  ...
  <FaultRules>
    ...
  </FaultRules>

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>ReturnGenericError</Name>
    </Step>
  </DefaultFaultRule>

  <HTTPTargetConnection>
    <URL>http://mocktarget.apigee.net</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

DefaultFaultRule은 대체로 기술 지원에 대한 연락처 정보가 포함된 메시지와 같이 예상치 못한 오류에 대한 일반 오류 메시지를 반환하는 데 사용됩니다. 이 기본 응답은 개발자에게 친숙한 정보를 제공하는 동시에 시스템을 손상시키는 데 사용될 수 있는 백엔드 URL 또는 기타 정보를 난독화하는 두 가지 용도로 사용됩니다.

예를 들어 다음 AssignMessage 정책을 정의하여 일반 오류를 반환할 수 있습니다.

<AssignMessage name="ReturnGenericError">
  <Set>
    <Payload type="text/plain">SERVICE UNAVAILABLE. PLEASE CONTACT SUPPORT: support@company.com.</Payload>
  </Set>
</AssignMessage>

다른 FaultRule이 이미 실행된 경우에도 DefaultFaultRule을 실행하려면 <DefaultFaultRule> 태그에 <AlwaysEnforce> 요소를 포함합니다. DefaultFaultRule은 항상 마지막에 실행할 FaultRule입니다.

  <DefaultFaultRule name="fault-rule">
    <Step>
      <Name>ReturnGenericError</Name>
    </Step>
    <AlwaysEnforce>true</AlwaysEnforce>
  </DefaultFaultRule>

DefaultFaultRule의 용도 중 하나는 다른 방법으로 확인할 수 없는 경우 발생하는 오류 유형을 확인하는 것입니다. 예를 들어 확인할 수 없는 오류로 인해 API 프록시가 실패합니다. DefaultFaultRule을 사용하여 다음 AssignMessage 정책을 호출합니다. 이 정책은 응답에서 DefaultFaultHeader라는 헤더에 fault.name 값을 작성합니다.

<AssignMessage async="false" continueOnError="false" enabled="true" name="DefaultFaultRule">
  <DisplayName>DefaultFaultRule</DisplayName>
  <Set>
    <Headers>
      <Header name="DefaultFaultHeader">{fault.name}</Header>
    </Headers>
  </Set>
  <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
  <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

그런 다음 Edge 트레이스 도구 또는 응답에서 헤더를 보고 오류의 원인을 확인할 수 있습니다.

PostClientFlow에 메시지 로깅 추가

PostClientFlow는 프록시가 오류 상태로 전환된 후 실행되는 유일한 흐름입니다. 이 흐름에는 MessageLogging 정책만 연결할 수 있으며, 응답이 클라이언트로 다시 전송된 후에 실행됩니다. 이 흐름에 MessageLogging 정책을 연결하는 것은 기술적으로 오류를 처리하는 것이 아니지만, 오류 발생 시 정보를 로깅하는 데 사용할 수 있습니다. 프록시 성공 여부와 관계없이 실행되므로 PostClientFlow에 Message Logging 정책을 적용하고 항상 실행되도록 보장할 수 있습니다.

현재 흐름 내에서 정책 오류 처리

지금까지 표시된 예시에서는 모두 ProxyEndpoint 또는 TargetEndpoint에서 FaultRule을 사용하여 오류 상태의 일부로 정책 오류를 처리합니다. 그 이유는 정책의 continueOnError 요소의 기본값이 false이기 때문입니다. 즉, 정책에서 오류가 발생하면 제어가 오류 상태로 전환됩니다. 오류 상태가 되면 일반 파이프라인으로 제어를 반환할 수 없으며 일반적으로 호출 앱에 일부 형식의 오류 메시지를 반환합니다.

하지만 정책에 대한 continueOnError 요소를 true로 설정하면 제어는 현재 흐름에 유지되고 파이프라인의 다음 정책은 오류를 일으킨 정책 다음에 실행됩니다. 현재 흐름에서 오류를 처리할 때의 이점은 오류를 복구하여 요청 처리를 완료할 수 있다는 것입니다.

다음은 continueOnError 요소가 true:로 설정된 verify-api-key라는 VerifyAPIKey 정책입니다.

<VerifyAPIKey async="false" continueOnError="true" enabled="true" name="verify-api-key">
  <DisplayName>Verify API Key</DisplayName>
  <APIKey ref="request.queryparam.apikey"/>
</VerifyAPIKey>

API 키가 없거나 유효하지 않은 경우 VerifyAPIKey 정책oauthV2.verify-api-key.failed 변수를 true로 설정하지만, 처리는 현재 흐름에서 지속됩니다.

그런 다음 ProxyEndpoint의 PreFlow 단계로 VerifyAPIKey 정책을 추가합니다.

<ProxyEndpoint name="default">
  ...
  <PreFlow name="PreFlow">
    <Request>
      <Step>
        <Name>verify-api-key</Name>
      </Step>
      <Step>
        <Name>FaultInFlow</Name>
        <Condition>(oauthV2.verify-api-key.failed = "true")</Condition>
      </Step>
    </Request>
    <Response/>
  </PreFlow>      
</ProxyEndpoint>  

PreFlow의 다음 단계에서 조건을 사용하여 오류가 있는지 테스트합니다. VerifAPIKey 정책에서 오류가 발생하면 FaultInFlow 정책이 실행됩니다. 그렇지 않으면 FaultInFlow 정책을 건너뜁니다. FaultInFlow 정책은 오류를 로깅하거나 오류 해결을 시도하거나 다른 작업을 수행하는 등 다양한 작업을 수행할 수 있습니다.

RaiseFault 정책을 사용하여 오류 트리거

흐름에서 언제든지 RaiseFault 정책을 사용하여 오류를 트리거할 수 있습니다. RaiseFault 정책이 실행되면 현재 흐름을 종료하고 제어를 오류 상태로 전송합니다.

RaiseFault 정책의 한 가지 용도는 다른 정책이 감지하지 못하는 특정 조건을 테스트하는 것입니다. 위의 예시에서는 조건이 충족되는 경우 FaultInFlow 정책이 실행되도록 하는 PreFlow <Step> 태그에 <Condition> 태그를 추가했습니다. FaultInFlow가 RaiseFault 정책인 경우 제어가 오류 상태로 전환됩니다. 또는 흐름에 RaiseFault 정책을 삽입하여 FaultRule을 디버깅하고 테스트할 수 있습니다.

RaiseFault 정책이 오류를 트리거하면 다음 FaultRule 및 조건을 사용하여 처리할 수 있습니다.

<FaultRule name="raisefault_rule">
  <Step>
    <Name>{policy_name}</Name>
  </Step>
  <Condition>(fault.name = "RaiseFault")</Condition>
</FaultRule>

조건은 RaiseFault라는 오류를 테스트합니다. RaiseFault 정책은 항상 fault.name 값을 RaiseFault로 설정합니다.

대상 서버의 HTTP 오류 코드 커스텀 처리

이전 섹션에 표시된 예시는 정책에서 생성된 오류에 적용됩니다. 하지만 전송 수준 오류, 즉 대상 서버에서 반환되는 HTTP 오류에 대한 커스텀 응답을 만들 수도 있습니다. HTTP 오류의 응답을 제어하려면 HTTP 응답 코드를 처리하도록 TargetEndpoint를 구성합니다.

기본적으로 Edge는 1xx-3xx 범위의 HTTP 응답 코드를 '성공'으로, 4xx-5xx 범위의 HTTP 응답 코드를 '실패'로 간주합니다. 즉, HTTP 응답 코드 4xx-5xx를 갖는 백엔드 서비스의 응답은 자동으로 오류 상태를 호출한 후 요청하는 클라이언트에 오류 메시지를 직접 반환합니다.

모든 HTTP 응답 코드에 대한 커스텀 핸들러를 만들 수 있습니다. 예를 들어 4xx-5xx 범위에 있는 모든 HTTP 응답 코드를 '실패'로 취급하지 않고 5xx만 처리하거나, HTTP 응답 코드 400 및 500에 커스텀 오류 메시지를 반환할 수 있습니다.

다음 예에서는 success.codes 속성을 사용하여 HTTP 응답 코드 400 및 500을 기본 HTTP 코드와 함께 성공으로 취급하도록 TargetEndpoint를 구성합니다. 이러한 코드를 성공으로 취급하면 TargetEndpoint는 오류 상태를 호출하지 않고 응답 메시지 처리를 수행합니다.

<TargetEndpoint name="default">
  ...
  <HTTPTargetConnection>
    <Properties>
          <Property name="success.codes">1xx,2xx,3xx,400,500</Property>
    </Properties>
    <URL>http://weather.yahooapis.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

이 예에서 볼 수 있듯이 와일드 카드를 사용하여 success.codes 속성을 값 범위로 설정할 수 있습니다.

success.codes 속성을 설정하면 기본값을 덮어씁니다. 따라서 기본 성공 코드 목록에 HTTP 코드 400을 추가하려면 이 속성을 다음과 같이 설정합니다.

<Property name="success.codes">1xx,2xx,3xx,400</Property>

하지만 HTTP 코드 400만 성공 코드로 취급하려면 속성을 다음과 같이 설정합니다.

<Property name="success.codes">400</Property>

이제 HTTP 응답 코드 400 및 500에 대한 커스텀 핸들러를 정의하여 요청 앱에 커스텀 응답 메시지를 반환할 수 있습니다. 다음 TargetEndpoint는 ReturnError라는 정책을 사용하여 HTTP 400 및 500 응답 코드를 처리합니다.

<TargetEndpoint name="default">
  <PreFlow name="PreFlow">
    <Request/>
    <Response>
      <Step>
        <Name>ReturnError</Name>
        <Condition>(response.status.code = 400) or (response.status.code = 500)</Condition>
      </Step>
    </Response>
  </PreFlow>

  <HTTPTargetConnection>
    <Properties>
      <Property name="success.codes">1xx,2xx,3xx,400,500</Property>
    </Properties>
    <URL>http://weather.yahooapis.com</URL>
  </HTTPTargetConnection>
</TargetEndpoint>

이 TargetEndpoint 구성은 TargetEndpoint에서 HTTP 응답 코드 400 또는 500이 발생할 때마다 ReturnError라는 정책에서 응답을 처리하게 합니다.

오류 분류

API 서비스는 오류를 다음 카테고리 및 하위 카테고리로 분류합니다.

카테고리 하위 카테고리 오류 이름 설명
Messaging 메시지 흐름 중에 발생하는 오류(정책 실패 제외)
커스텀 오류 {fault_name} RaiseFault 정책을 사용하여 API 프록시에서 명시적으로 처리한 모든 오류
응답 코드 InternalServerError, NotFound HTTP 오류 코드 5xx, 4xx
라우팅 오류 NoRoutesMatched 요청에 대해 TargetEndpoint를 선택하지 못했습니다.
분류 오류 NotFound 요청 URI가 ProxyEndpoint 구성의 BasePath와 일치하지 않는 경우(즉, API 프록시가 클라이언트 앱 요청의 URL과 일치하지 않음)
전송 HTTP 전송 수준 오류
연결 ConnectionRefused, ConnectionReset, ConnectionTimeout 네트워크 또는 전송 수준 연결을 설정하는 동안 오류가 발생합니다.
유효성 검사 요청 ContentLengthMissing, HostHeaderMissing 모든 요청에서 시맨틱스 검사 중에 오류가 발생합니다.
응답 유효성 검사 모든 응답에서 시맨틱스 검사 중에 오류가 발생합니다.
IO 오류 SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError 클라이언트 또는 대상 엔드포인트의 읽기/쓰기 오류, 제한 시간, TLS/SSL 오류, 청크 오류
시스템 정의되지 않은 런타임 오류
메모리 OutOfMemory, GCOverLimit 메모리 관련 오류
Thread RogueTaskTerminated 실패한 작업 종료와 같은 오류
정책 각 정책 유형의 오류는 정책 참조에 정의되어 있습니다.

오류에는 항상 실패 원인에 대한 텍스트 설명이 동반됩니다. 시스템에서 오류가 발생하면 문제 해결을 지원하기 위해 속성 집합이 채워집니다. 오류에는 다음 정보가 포함되어 있습니다.

  • 이유
  • 사용자 정의 커스텀 속성