Xử lý lỗi

Bạn đang xem tài liệu về Apigee Edge.
Chuyển đến tài liệu về Apigee X.
thông tin

Nhiều tình trạng lỗi có thể phát sinh trong khi proxy API đang thực hiện yêu cầu từ ứng dụng. Ví dụ: các proxy API có thể gặp sự cố mạng khi giao tiếp với các dịch vụ phụ trợ, ứng dụng có thể hiển thị thông tin đăng nhập đã hết hạn, thông báo yêu cầu có thể được định dạng không chính xác, v.v.

Khi xảy ra lỗi sau khi ứng dụng khách gọi proxy API, thông báo lỗi sẽ được trả về cho ứng dụng. Theo mặc định, máy khách sẽ nhận được một thông báo lỗi thường rất khó hiểu kèm theo thông tin chi tiết hoặc hướng dẫn. Tuy nhiên, nếu muốn thay thế các thông báo lỗi mặc định bằng các thông báo tuỳ chỉnh hữu ích hơn và thậm chí làm phong phú những thông báo đó bằng các tiêu đề HTTP bổ sung, thì bạn cần thiết lập cách xử lý lỗi tuỳ chỉnh trong Edge.

Việc xử lý lỗi tuỳ chỉnh cũng cho phép bạn thêm chức năng như ghi nhật ký thông báo mỗi khi xảy ra lỗi.

Trước khi nói về cách triển khai cách xử lý lỗi tuỳ chỉnh trong proxy API, bạn nên hiểu cách xảy ra lỗi và cách các proxy API phản ứng với lỗi đó.

Video

Hãy xem các video sau để tìm hiểu thêm về cách xử lý lỗi.

Video Nội dung mô tả
Giới thiệu về quy trình xử lý lỗi và quy trình lỗi Tìm hiểu về cách xử lý lỗi và điều gì xảy ra khi xảy ra lỗi trong proxy API.
Xử lý lỗi bằng quy tắc về lỗi Tìm hiểu cách xử lý lỗi bằng quy tắc về lỗi.
Tăng lỗi tuỳ chỉnh bằng chính sách RaiseFault Tăng lỗi tuỳ chỉnh trong thời gian chạy API bằng chính sách RaiseFault.
Xác định các quy tắc lỗi trong proxy API và điểm cuối mục tiêu Xác định các quy tắc lỗi trong proxy API và điểm cuối đích, đồng thời tìm hiểu sự khác biệt.
Tìm hiểu thứ tự thực thi của các quy tắc lỗi Hiểu thứ tự thực thi của các quy tắc lỗi trong proxy API và điểm cuối nhắm mục tiêu.
Xác định quy tắc lỗi mặc định Xác định quy tắc lỗi mặc định để xử lý các lỗi chung trong API.

Cách lỗi xảy ra

Trước tiên, chúng ta sẽ chỉ xem xét cách xảy ra lỗi. Việc biết được cách xảy ra lỗi giúp bạn lập kế hoạch cho nhiều tình huống mà bạn muốn triển khai cách xử lý lỗi tuỳ chỉnh.

Lỗi tự động

Proxy API sẽ tự động gửi lỗi trong các trường hợp sau:

  • Chính sách tạo ra lỗi. Ví dụ: nếu một lệnh gọi API gửi một khoá đã hết hạn, thì chính sáchVerifyAPIKey sẽ tự động báo lỗi; hoặc nếu số lượng lệnh gọi API vượt quá một giới hạn nhất định, thì Chính sách hạn mức hoặc chính sách SpikeArrest sẽ báo lỗi. (Xem Tài liệu tham khảo về lỗi chính sách để biết các loại lỗi mà chính sách có thể gửi).
  • Đã xảy ra sự cố trong quy trình thông báo proxy API, chẳng hạn như lỗi định tuyến.
  • Đã xảy ra lỗi phụ trợ, chẳng hạn như lỗi HTTP do lỗi cấp giao thức, lỗi TLS/SSL hoặc dịch vụ đích không có sẵn.
  • Đã xảy ra lỗi cấp hệ thống, chẳng hạn như một ngoại lệ hết bộ nhớ.

Để biết thêm thông tin về những lỗi này, hãy xem phần Phân loại lỗi trong chủ đề này.

Lỗi tuỳ chỉnh

Trong trường hợp không có lỗi tự động, bạn nên gửi một lỗi tuỳ chỉnh; ví dụ: nếu phản hồi chứa từ "không có" hoặc nếu mã trạng thái HTTP lớn hơn 201. Bạn có thể thực hiện việc này bằng cách thêm RaiseFault vào vị trí thích hợp trong luồng proxy API.

Bạn có thể thêm chính sách RaiseFault vào quy trình proxy API giống như cách thêm bất kỳ chính sách nào khác. Trong ví dụ về cấu hình proxy sau đây, chính sách Raise-Fault-1 được đính kèm với phản hồi TargetEndpoint. Nếu từ "không có" hiện diện trong phản hồi của dịch vụ mục tiêu, chính sách RaiseFault sẽ được thực thi và gửi lỗi.

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

Việc này chỉ cho bạn thấy rằng bạn có thể tạo ra lỗi tuỳ chỉnh. Chúng ta sẽ tìm hiểu chi tiết hơn về chính sách RaiseFault trong phần FaultRules và chính sách RaiseFault.

Để biết thêm ví dụ, hãy xem các bài đăng sau trên Diễn đàn cộng đồng API:

Hoạt động của proxy API khi xảy ra lỗi

Dưới đây là những gì sẽ xảy ra khi proxy gửi lỗi.

Thoát quy trình proxy

Khi gặp lỗi, proxy API sẽ thoát khỏi quy trình luồng thông thường, chuyển sang trạng thái lỗi và trả về thông báo lỗi cho ứng dụng khách. Sau khi proxy API chuyển sang trạng thái lỗi, proxy API sẽ không thể quay lại quy trình xử lý thông thường.

Ví dụ: giả sử một proxy API có các chính sách theo thứ tự sau đây trong yêu cầu ProxyEndpoint:

  1. Xác minh khoá API
  2. Hạn mức
  3. JSON sang XML

Nếu xảy ra lỗi trong quá trình xác minh khoá API, proxy API sẽ chuyển sang trạng thái lỗi. Các chính sách Hạn mức và JSON sang XML không được thực thi, proxy sẽ không chuyển đến TargetEndpoint và thông báo lỗi được trả về ứng dụng.

Kiểm tra lỗi FaultRules

Ở trạng thái lỗi, proxy API cũng kiểm tra sự hiện diện của các thành phần sau (theo thứ tự) trong cấu hình proxy API trước khi trả về thông báo lỗi mặc định cho ứng dụng:

  1. Phần <FaultRules>, chứa logic để kích hoạt các thông báo lỗi tuỳ chỉnh (và các chính sách khác) dựa trên những điều kiện cụ thể mà bạn xác định.
  2. Phần <DefaultFaultRule> sẽ kích hoạt thông báo lỗi mặc định trong các trường hợp sau:
    • Không có <FaultRules> nào được xác định.
    • Không có <FaultRules> hiện tại nào được thực thi.
    • Phần tử <AlwaysEnforce> được đặt thành true.

Về cơ bản, proxy API cho bạn cơ hội trả về một thông báo lỗi tuỳ chỉnh và kích hoạt logic khác. Nếu proxy không tìm thấy mục nào trong số đó, hoặc các mục đó tồn tại nhưng không có lỗi tuỳ chỉnh nào được kích hoạt, thì proxy sẽ gửi thông báo mặc định do Edge tạo riêng.

Ví dụ về cách xử lý lỗi đơn giản

Hãy bắt đầu bằng một ví dụ đơn giản, trong đó lệnh gọi đến một proxy API không chứa khoá API bắt buộc. Theo mặc định, sau đây là phản hồi được trả về ứng dụng khách:

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"}}}

Người dùng API của bạn có thể phát hiện ra thông báo lỗi, nhưng có thể thì không. Ngoài ra, nhiều lỗi mặc định tinh vi và khó giải mã hơn.

Là nhà phát triển API, bạn có thể thay đổi thông báo này để đáp ứng nhu cầu của tất cả những người sau cùng sẽ nhận được thông báo lỗi, cho dù đó là nhà phát triển ứng dụng iOS hay nhóm kiểm thử nội bộ có yêu cầu riêng về định dạng thông báo lỗi.

Dưới đây là ví dụ cơ bản về cách bạn sẽ tạo thông báo lỗi tuỳ chỉnh để xử lý lỗi này. Điều này đòi hỏi 1) chính sách xác định thông báo tuỳ chỉnh và 2) một FaultRule thực thi chính sách khi proxy chuyển sang trạng thái lỗi.

1. Tạo chính sách xác định thông báo tuỳ chỉnh

Trước tiên, hãy tạo một chính sách xác định thông báo lỗi tuỳ chỉnh. Bạn có thể sử dụng bất kỳ loại chính sách nào, chẳng hạn như AssignMessage policy, có thể đặt trọng tải và các tiêu đề HTTP không bắt buộc như mã trạng thái và cụm từ lý do. Chỉ định Tin nhắn là lựa chọn lý tưởng cho việc này. API này cho phép bạn kiểm soát tải trọng thông báo, đặt mã trạng thái HTTP khác, đặt một cụm từ lý do HTTP khác và thêm tiêu đề HTTP.

Đừng đính kèm chính sách này vào bất kỳ quy trình nào trong proxy API. Chỉ cần nó tồn tại trong gói proxy là đủ. Để thực hiện việc này trong trình chỉnh sửa proxy giao diện người dùng quản lý, hãy chuyển đến thẻ Phát triển và trong ngăn Điều hướng rồi nhấp vào biểu tượng dấu + trên thanh Chính sách.

Thao tác này cho phép bạn tạo một chính sách mà không cần đính kèm chính sách đó vào một luồng trong proxy API. Chính sách không được đính kèm với bất kỳ quy trình nào sẽ bị gắn cờ bằng biểu tượng "tách biệt" trong danh sách Chính sách, như minh hoạ bên cạnh chính sách về thông báo quan trọng đối với API trình bày trong hình trước.

Sau đây là ví dụ về Chính sách assignMessage:

  • Trả về thông báo JSON.
  • Đặt mã trạng thái HTTP (911, đây là một mã trạng thái rõ ràng không tồn tại chỉ để minh hoạ tính linh hoạt của bạn). Mã trạng thái sẽ xuất hiện trong tiêu đề HTTP.
  • Đặt một cụm từ lý do HTTP (để thay thế cụm từ mặc định "Không được phép" cho lỗi thiếu khoá API này). Cụm từ lý do sẽ xuất hiện bên cạnh mã trạng thái trong tiêu đề HTTP.
  • Tạo và điền tiêu đề HTTP mới có tên là invalidKey.
<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>

Khi chính sách này được thực thi, phản hồi cho ứng dụng khách sẽ có dạng như sau. So sánh thông tin đó với câu trả lời mặc định được hiển thị trước đó.

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."}

Vâng, điều này hơi ngớ ngẩn một chút, nhưng nó cho bạn thấy những điều có thể. Ít nhất hiện tại, nhà phát triển nhận được thông báo biết rằng họ đã quên bao gồm khoá API làm tham số truy vấn.

Nhưng chính sách này được thực thi bằng cách nào? Phần tiếp theo sẽ cho bạn thấy.

2. Tạo <FaultRule> kích hoạt chính sách

Trong các phần <ProxyEndpoint> hoặc <TargetEndpoint> của cấu hình proxy, bạn sẽ thêm một khối XML <FaultRules> chứa một hoặc nhiều phần <FaultRule> riêng lẻ. Mỗi FaultRule đại diện cho một lỗi khác nhau mà bạn muốn xử lý. Trong ví dụ đơn giản này, chúng tôi chỉ sử dụng một FaultRule để cho bạn thấy các thành phần của lỗi đó.

Bạn cũng nên thêm <DefaultFaultRule> để cung cấp thông báo lỗi chung tuỳ chỉnh nếu không có FaultRules nào được thực thi.

Ví dụ:

<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>

Điểm chính:

  • FaultRules được xác định trong ProxyEndpoint. Điều này rất quan trọng. Bạn có thể tìm hiểu thêm về việc đặt FaultRules vào ProxyEndpoint so với TargetEndpoint sau.
  • <Name> – Tên của chính sách sẽ thực thi. Tên được lấy từ thuộc tính name của chính sách trên phần tử mẹ, như trong ví dụ về chính sách trước đó.
  • <Condition> – Edge đánh giá điều kiện và chỉ thực thi chính sách nếu điều kiện đó là đúng. Nếu có nhiều FaultRules được đánh giá là true, Edge sẽ thực thi điều kiện đầu tiên đúng. (Lưu ý quan trọng: Thứ tự đánh giá các FaultRules (từ trên xuống dưới hoặc từ dưới lên trên) sẽ khác nhau giữa TargetEndpoint và ProxyEndpoint, như được mô tả trong phần Multiple FaultRules và logic thực thi.) Nếu bạn không thêm điều kiện, thì FaultRule sẽ tự động có giá trị true. Nhưng đó không phải là phương pháp hay nhất. Mỗi FaultRule phải có một điều kiện riêng.

  • <DefaultFaultRule> – Nếu không có FaultRule tuỳ chỉnh nào được thực thi, thì <DefaultFaultRule> sẽ được thực thi và gửi một thông báo tuỳ chỉnh chung chung hơn thay vì thông báo khó hiểu do Edge tạo. <DefaultFaultRule> cũng có thể có <Condition>, nhưng trong hầu hết trường hợp, bạn sẽ không đưa vào, vì bạn muốn nó thực thi bất kể phương án cuối cùng là gì.

    DefaultFaultRule thường được dùng để trả về một thông báo lỗi chung đối với mọi lỗi không mong muốn. Ví dụ: một thông báo chứa thông tin liên hệ của bộ phận hỗ trợ kỹ thuật. Phản hồi mặc định này có mục đích kép là cung cấp thông tin thân thiện với nhà phát triển, đồng thời làm rối mã nguồn của các URL phụ trợ hoặc thông tin khác có thể được dùng để xâm phạm hệ thống.

Nhiều FaultRules và logic thực thi

Trong phần Ví dụ về cách xử lý lỗi đơn giản, chúng tôi đã sử dụng một ví dụ đơn giản về một FaultRule và điều kiện duy nhất. Trong một dự án API thực tế, với tất cả các lỗi có thể xảy ra, bạn có thể sẽ gặp nhiều lỗi FaultRules và một DefaultFaultRule trong cả <ProxyEndpoint><TargetEndpoint>. Tuy nhiên, cuối cùng, chỉ một FaultRule được thực thi khi proxy API chuyển sang trạng thái lỗi.

Phần này mô tả logic mà Edge sử dụng trong quá trình xử lý FaultRules, từ cách đạt được một FaultRule duy nhất để thực thi cho đến cách xử lý các điều kiện Bước "bên trong" khi FaultRule được kích hoạt. Phần này cũng đưa ra hướng dẫn về thời điểm xác định FaultRules trong <ProxyEndpoint> so với <TargetEndpoint>, đồng thời mô tả mối quan hệ giữa FaultRules và chính sách RaiseFault.

Thực thi FaultRules

Tóm lại, đây là logic mà Edge sử dụng khi một proxy API chuyển sang trạng thái lỗi. Xin lưu ý rằng có sự khác biệt nhỏ giữa việc đánh giá FaultRules trong ProxyEndpoint so với TargetEndpoint.

  1. Edge đánh giá FaultRules trong ProxyEndpoint hoặc TargetEndpoint, tuỳ thuộc vào nơi xảy ra lỗi:
    • ProxyEndpoint – Edge bắt đầu với <FaultRule> dưới cùng trong XML cấu hình và hoạt động theo cách này, đánh giá <Condition> của từng <FaultRule> (điều kiện "bên ngoài", không phải điều kiện <Step> "bên trong").
    • TargetEndpoint – Edge bắt đầu với <FaultRule> trên cùng trong XML cấu hình và hoạt động theo chiều dọc, đánh giá <Condition> của từng <FaultRule> (điều kiện "bên ngoài", không phải điều kiện <Step> "bên trong").
  2. Thực thi FaultRule đầu tiên có điều kiện đúng. Nếu FaultRule không có điều kiện nào, thì điều kiện đó sẽ đúng theo mặc định.
    • Khi một FaultRule được thực thi, tất cả các Bước bên trong FaultRule sẽ được đánh giá theo thứ tự, từ trên xuống dưới trong cấu hình XML. Các bước không có điều kiện sẽ được thực thi tự động (chính sách sẽ được thực thi) và các bước có <Condition> được đánh giá là "true" sẽ được thực thi (các điều kiện được đánh giá là "false" sẽ không được thực thi).
    • Nếu một FaultRule được thực thi nhưng không có Bước nào trong FaultRule được thực thi (vì điều kiện của chúng được đánh giá là "false"), thông báo lỗi mặc định do Edge tạo sẽ được trả về cho ứng dụng. <DefaultFaultRule> không được thực thi vì Edge đã thực thi một FaultRule.

  3. Nếu không có FaultRule nào được thực thi, Edge sẽ thực thi <DefaultFaultRule> (nếu có).

Sau đây là các ví dụ về nhận xét cùng dòng.

Thực thi ProxyEndpoint

Phần đánh giá ProxyEndpoint FaultRules từ dưới lên trên, vì vậy, hãy bắt đầu đọc ở lỗi FaultRule cuối cùng trong mẫu sau và tìm hiểu sâu hơn. Xem DefaultFaultRule cuối cùng.

<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>

Thực thi TargetEndpoint

Bạn có thể đánh giá TargetEndpoint FaultRules từ trên xuống dưới, vì vậy, hãy bắt đầu đọc FaultRule đầu tiên trong mẫu sau và tìm hiểu sâu hơn. Xem DefaultFaultRule cuối cùng.

<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>

Thứ tự quy tắc lỗi

Như bạn có thể thấy trong ví dụ trước, thứ tự đặt FaultRules quan trọng, tuỳ thuộc vào việc lỗi xảy ra trong ProxyEndpoint hay TargetEndpoint.

Ví dụ:

Đơn đặt hàng ProxyEndpoint Thứ tự TargetEndpoint

Trong ví dụ sau, vì việc đánh giá từ dưới lên trên nên FaultRule 3 được thực thi, có nghĩa là FaultRules 2 và 1 sẽ không được đánh giá.

5. FaultRule 1: FALSE

4. FaultRule 2: TRUE

3. FaultRule 3: TRUE

2. FaultRule 4: FALSE

1. FaultRule: 5 FALSE

Trong ví dụ sau, vì việc đánh giá từ trên xuống dưới nên FaultRule 2 được thực thi, có nghĩa là FaultRules 3, 4 và 5 sẽ không được đánh giá.

1. FaultRule 1: FALSE

2. FaultRule 2: TRUE

3. FaultRule 3: TRUE

4. FaultRule 4: FALSE

5. FaultRule: 5 FALSE

Chính sách cần đưa vào

Bạn có thể thực thi bất kỳ chính sách nào từ một FaultRule bằng cách đặt các chính sách đó vào phần Các bước. Ví dụ: bạn có thể thực thi assignMessage chính sách để định dạng phản hồi cho ứng dụng khách, sau đó ghi nhật ký thông báo bằng chính sáchMessageLogging. Các chính sách được thực thi theo thứ tự mà bạn đặt (từ trên xuống dưới trong tệp XML).

Quy tắc lỗi CHỈ được kích hoạt trong trạng thái lỗi (về continueOnError)

Tiêu đề này có vẻ như chúng ta đang lặp lại, nhưng có một vấn đề cụ thể mà bạn cần lưu ý đối với lỗi proxy khiến proxy API chuyển sang trạng thái lỗi – hay nói cách khác là không chuyển sang trạng thái lỗi: thuộc tính continueOnError của chính sách.

Tóm lại: Một proxy API chỉ đánh giá <FaultRules><DefaultFaultRule> nếu proxy đó đã chuyển sang trạng thái lỗi. Điều đó có nghĩa là ngay cả khi một điều kiện FaultRule được đánh giá là true (đúng), thì nó sẽ không được kích hoạt nếu proxy không ở trạng thái lỗi.

Tuy nhiên, sau đây là ví dụ về lỗi xảy ra và proxy không chuyển sang trạng thái lỗi. Trên bất kỳ chính sách nào, bạn cũng có thể đặt một thuộc tính trên phần tử mẹ có tên là continueOnError. Thuộc tính đó rất quan trọng đối với việc xử lý lỗi, vì thuộc tính này quyết định liệu proxy có chuyển sang trạng thái lỗi nếu chính sách không thành công hay không. Trong hầu hết trường hợp, bạn nên giữ lại continueOnError="false" mặc định. Thao tác này sẽ đặt proxy ở trạng thái lỗi nếu chính sách này không thành công và quá trình xử lý lỗi tuỳ chỉnh của bạn sẽ được kích hoạt. Tuy nhiên, nếu continueOnError="true" (ví dụ: nếu bạn không muốn Chú thích dịch vụ ngừng thực thi proxy), proxy sẽ không chuyển sang trạng thái lỗi nếu chính sách đó không thành công và proxy sẽ không xem FaultRules của bạn.

Để biết thông tin về cách ghi lỗi khi continueOnError="true", hãy xem phần Xử lý lỗi chính sách trong quy trình hiện tại.

Nơi xác định FaultRules: ProxyEndpoint hoặc TargetEndpoint

Khi một proxy API gặp lỗi, lỗi đó sẽ xảy ra trong <ProxyEndpoint> (yêu cầu gửi từ hoặc phản hồi ứng dụng khách) hoặc trong <TargetEndpoint> (yêu cầu đến hoặc phản hồi của dịch vụ mục tiêu). Bất cứ nơi nào lỗi đó xảy ra là nơi Edge tìm FaultRules.

Ví dụ: nếu không có máy chủ mục tiêu (mã trạng thái HTTP 503), thì proxy API sẽ chuyển sang trạng thái lỗi trong phản hồi <TargetEndpoint> và quy trình proxy API thông thường sẽ không tiếp tục đến <ProxyEndpoint>. Nếu bạn chỉ xác định FaultRules trong <ProxyEndpoint>, thì chúng sẽ không xử lý lỗi đó.

Sau đây là một ví dụ khác. Nếu chính sách RaiseFault trong phản hồi <ProxyEndpoint> kích hoạt lỗi, thì FaultRule trong <TargetEndpoint> sẽ không được thực thi.

FaultRules và chính sách RaiseFault

Các quy tắc lỗi và chính sách RaiseFault có thể là những cách khác để xử lý lỗi và trong một số trường hợp thì điều này cũng đúng. Nhưng chúng cũng hoạt động cùng nhau. Phần này giải thích mối quan hệ giữa hai vấn đề. Việc hiểu rõ mối quan hệ này sẽ giúp bạn thiết kế cách xử lý lỗi, đặc biệt là nếu muốn sử dụng cả hai.

Tóm lại:

  • Các quy tắc lỗi luôn được đánh giá khi một proxy API chuyển sang trạng thái lỗi.
  • Chính sách RaiseFault là một cách để đặt proxy API ở trạng thái lỗi khi lẽ ra lỗi sẽ không xảy ra.

    Ví dụ: Trong trường hợp bạn muốn báo lỗi nếu mã trạng thái HTTP trong phản hồi của dịch vụ mục tiêu lớn hơn 200, thì bạn cần thêm chính sách RaiseFault trong quy trình phản hồi. URL sẽ có dạng như sau:

    <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> 
    

    Chính sách RaiseFault cũng gửi một thông báo lỗi đến ứng dụng khách.

Điều gì xảy ra khi chính sách RaiseFault kích hoạt một lỗi, khiến proxy có trạng thái lỗi, dẫn đến việc có thể thực thi FaultRule? Đây là nơi mà mọi thứ có thể hơi phức tạp. Nếu chính sách RaiseFault trả về một thông báo lỗi một FaultRule được kích hoạt đồng thời trả về một thông báo lỗi, thì nội dung nào sẽ được trả về ứng dụng khách?

  • Vì FaultRule hoặc DefaultFaultRule được thực thi sau chính sách RaiseFault, nên dữ liệu phản hồi FaultRule sẽ chiến thắng.
  • Dữ liệu phản hồi theo chính sách RaiseFault (mã trạng thái, cụm từ lý do hoặc tải trọng thông báo) được sử dụng nếu dữ liệu đó không được thiết lập bởi FaultRule hoặc DefaultFaultRule.
  • Nếu cả chính sách RaiseFault và FaultRule đều thêm tiêu đề HTTP tuỳ chỉnh, thì cả hai tiêu đề này đều được đưa vào phản hồi. Tên tiêu đề trùng lặp sẽ tạo ra một tiêu đề có nhiều giá trị.

Dưới đây là ví dụ về nội dung được đặt theo chính sách RaiseFault và FaultRule cũng như nội dung được trả về ứng dụng khách. Các mẫu này được thiết kế ngắn gọn, không dành cho các phương pháp hay nhất.

Ứng dụng khách nhận được:

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

<- Chính sách quy tắc lỗi sẽ đặt chế độ cài đặt này:

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

<- Chính sách RaiseFault thiết lập chế độ này:

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

Điều kiện xây dựng

Điều kiện là yếu tố then chốt để thực thi FaultRule. Bạn tạo điều kiện FaultRule giống như cách bạn thực hiện cho các điều kiện khác trong Edge, chẳng hạn như đối với luồng có điều kiện hoặc điều kiện RaiseFault.

Để làm rõ phần còn lại của phần này, dưới đây là một quy tắc mẫu về lỗi có điều kiện bên ngoài FaultRule và điều kiện Bước bên trong.

<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>

Các biến cụ thể cho lỗi về chính sách

Các biến fault.name{policy_namespace}.{policy_name}.failed có sẵn khi chính sách báo lỗi.

fault.name

Khi một chính sách không thành công, hãy phát hiện lỗi trong một điều kiện bằng cách sử dụng biến fault.name. Ví dụ:

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

Tên lỗi xuất hiện trong thông báo lỗi mặc định. Ví dụ: trong ví dụ sau, tên lỗi là FailedToResolveAPIKey. Trong trường hợp này, một biến luồng có tên là fault.name sẽ được đặt thành giá trị FailedToResolveAPIKey.

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

Vì vậy, điều kiện sẽ trông giống như sau:

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

Hãy xem Tài liệu tham khảo về lỗi chính sách để biết danh sách các lỗi về chính sách.

{policy_namespace}.{policy_name}.không thành công

Biến *.failed có sẵn khi một chính sách không thành công. Sau đây là ví dụ về biến *.failed cho các chính sách khác nhau. Đối với vùng chứa tên chính sách, hãy xem các biến luồng trong mỗi chủ đề tham khảo chính sách.

Các biến có sẵn khác

Khi một proxy API chuyển sang trạng thái lỗi, các biến duy nhất có thể sử dụng trong các điều kiện là:

  • Các biến của chính sách không thành công.
  • Các biến thông báo HTTP tồn tại tại thời điểm không thành công. Ví dụ: nếu lỗi được tạo ra trong phản hồi, thì FaultRule trong <TargetEndpoint> có thể sử dụng dữ liệu HTTP response.status.code, message.content, error.content, v.v. Hoặc nếu Chính sách về hạn mức không hoạt động, bạn có thể sử dụng biến ratelimit.{quota_policy_name}.exceed.count. Hãy dùng Công cụ theo dõicác chủ đề tham khảo về chính sách để xác định những biến và dữ liệu HTTP có sẵn.

Thông tin khác

Các phương pháp hay nhất để xử lý lỗi

Xử lý lỗi là một nhiệm vụ thiết kế kiến trúc chính để phát triển proxy API. Bạn cần dành thời gian để tìm hiểu cách thức và thời điểm xử lý lỗi, xác định thông báo lỗi và thiết kế định dạng thông báo lỗi. Sau khi (hoặc khi) bạn tìm ra những điều đó, hãy sử dụng các phương pháp hay nhất này để giúp bạn triển khai cách xử lý lỗi.

Sau đây là một số phương pháp hay nhất trong quá trình thiết kế và xử lý lỗi:

  • Đối với mỗi FaultRule, hãy cung cấp một <Condition> "bên ngoài" (đồng cấp với phần tử <Step>). Các quy tắc lỗi không có điều kiện bên ngoài sẽ tự động đánh giá là true (đúng). Điều kiện Bước "Bên trong" không được dùng để xác định xem một FaultRule là đúng hay sai. Các điều kiện về bước chỉ được đánh giá sau khi Edge thực thi FaultRule chứa các điều kiện đó. Trong một FaultRule, thường có nhiều bước với chính sách Chỉ định thông báo (hoặc chính sách khác), mỗi chính sách có một điều kiện về Bước.
  • Để xử lý lỗi trong nhiều chính sách thuộc cùng loại (ví dụ: nhiều chính sách Hạn mức), hãy tạo một FaultRule cho mỗi lỗi chính sách mà bạn có thể gặp phải. Ví dụ: tạo một FaultRule cho từng lỗi có thể xảy ra trong chính sách Hạn mức, chẳng hạn như QuotaViolation, InvalidMessageWeight, StartTimeNotSupported. (Xem Tài liệu tham khảo về lỗi chính sách để biết các lỗi liên quan đến chính sách. Khi phát hiện các lỗi khác cần xử lý, bạn có thể quay lại sau và thêm các lỗi đó vào FaultRules. Bạn có thể lặp lại, mặc dù bạn cần triển khai lại proxy.) Phương pháp này cho phép bạn phát hiện cùng một loại lỗi bất kể chính sách nào đưa ra lỗi đó, giúp XML của bạn trở nên hiệu quả.

    Sau đó, hãy sử dụng các điều kiện Bước bên trong nếu bạn cần kiểm soát lỗi chi tiết hơn. Ví dụ: nếu bạn đang thực thi cả hạn mức dành cho nhà phát triển riêng lẻ và hạn mức chung cho hai chính sách trong quy trình yêu cầu, hãy đặt điều kiện FaultRule "bên ngoài" được kích hoạt đối với lỗi QuotaViolation (được gửi khi vượt quá hạn mức trong một trong hai trường hợp). Sau đó, đặt điều kiện Bước để đánh giá các biến exceed.count trong cả hai chính sách hạn mức của bạn. Chỉ lỗi liên quan được gửi tới ứng dụng khách (vượt quá hạn mức dành cho nhà phát triển hoặc vượt quá hạn mức chung). Dưới đây là ví dụ về cấu hình này:

    <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>
    

    Để tham khảo một ví dụ khác, vui lòng tham khảo chuỗi bài đăng này trên Cộng đồng Apigee.

  • Để xử lý lỗi trong trường hợp bạn chỉ sử dụng một chính sách thuộc một loại, hãy cân nhắc thực thi một quy tắc lỗi duy nhất khi một chính sách đó gặp lỗi, đồng thời bao gồm nhiều bước để liên kết với từng lỗi có thể xảy ra. Việc này giúp XML của bạn luôn hiệu quả bằng cách sử dụng một FaultRule duy nhất thay vì nhiều FaultRules (một quy tắc cho mỗi loại lỗi). Ví dụ:

    <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>
    
  • Thêm FaultRules nơi lỗi sẽ xảy ra (phía máy khách <ProxyEndpoint> hoặc phía đích <TargetEndpoint>). Thêm FaultRules cho từng chính sách xuất hiện ở từng vị trí.
  • Trong FaultRules, bạn có thể thực thi bất kỳ loại chính sách nào có thể trả về một thông báo cho ứng dụng. Chính sáchassignMessage là lựa chọn lý tưởng cho trường hợp này. Ngoài ra, hãy cân nhắc ghi nhật ký thông báo bằng chính sáchMessageLogging nếu bạn muốn theo dõi lỗi.
  • Khi sử dụng chính sách RaiseFault cùng với FaultRules, hãy điều phối dữ liệu phản hồi được gửi lại khi cả chính sách RaiseFault và dữ liệu trả về FaultRule. Ví dụ: nếu chính sách RaiseFault đặt lại mã trạng thái HTTP, đừng để lỗi FaultRule đặt lại mã trạng thái. Trường hợp xấu nhất có thể xảy ra là mã trạng thái mặc định sẽ bị trả về ứng dụng khách.
  • Thực thi <DefaultFaultRule>:
    • Nếu bạn muốn một <DefaultFaultRule> luôn thực thi khi không có FaultRule nào khác thực thi, thì đừng thêm <Condition> vào đó.
    • Nếu bạn muốn một <DefaultFaultRule> luôn thực thi ngay cả khi một lỗi khác đã thực thi, hãy thêm phần tử con <AlwaysEnforce>true</AlwaysEnforce>.

Mô hình để xử lý lỗi tập trung và có thể sử dụng lại

Bài đăng sau đây trên thẻ Cộng đồng Apigee mô tả một mẫu hình để xử lý lỗi tập trung mà không trùng lặp mã:

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

Tạo FaultRules

Để thêm một FaultRule, bạn cần chỉnh sửa cấu hình XML của ProxyEndpoint hoặc TargetEndpoint. Bạn có thể sử dụng giao diện người dùng Edge để chỉnh sửa nội dung này trong ngăn Code (Mã) của chế độ xem Develop (Phát triển) cho một proxy API, hoặc chỉnh sửa tệp XML xác định ProxyEndpoint hoặc TargetEndpoint.

Nếu bạn tạo FaultRules trong giao diện người dùng quản lý, trước tiên, hãy tạo các chính sách mà bạn muốn thực thi, sau đó thêm các chính sách đó vào cấu hình FaultRule. (Bạn sẽ gặp lỗi trong giao diện người dùng nếu cố lưu FaultRule tham chiếu đến một chính sách chưa được tạo.)

Thêm chính sách vào FaultRule

Mặc dù bạn có thể đặt bất kỳ chính sách nào vào FaultRule, nhưng bạn thường dùng chính sáchAssignMessage để tạo thông báo phản hồi tuỳ chỉnh cho một điều kiện lỗi. AttributionMessage cho phép bạn định cấu hình phản hồi HTTP với tải trọng, mã trạng thái HTTP, tiêu đề và các phần tử cụm từ lý do.

Ví dụ bên dưới hiển thị cấu hình assignMessage thông thường:

<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>

Bây giờ, bạn có thể sử dụng chính sách này trong FaultRule. Hãy lưu ý cách bạn tham chiếu đến chính sách composeMessage theo tên trong FaultRule:

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

Khi bạn triển khai cấu hình ở trên, proxy API sẽ thực thi chính sách AttributionMessage có tên là fault_invalidkey bất cứ khi nào ứng dụng hiển thị khóa API không hợp lệ.

Bạn có thể thực thi nhiều chính sách trong một FaultRule, như trong ví dụ sau:

<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>

Các chính sách sẽ thực thi theo thứ tự được xác định. Ví dụ: bạn có thể sử dụng chính sáchMessageLogging, chính sách ExtractVariables, chính sáchAssignMessage hoặc bất kỳ chính sách nào khác trong FaultRule. Xin lưu ý rằng quá trình xử lý FaultRule sẽ dừng ngay lập tức nếu một trong những tình huống sau xảy ra:

  • Mọi chính sách trong FaultRule đều gây ra lỗi
  • Mọi chính sách trong FaultRule đều thuộc loại RaiseFault

Xác định thông báo lỗi tuỳ chỉnh được trả về từ FaultRule

Tốt nhất là bạn nên xác định các phản hồi lỗi rõ ràng từ API của mình. Bằng cách đó, bạn cung cấp thông tin nhất quán và hữu ích cho khách hàng của mình.

Ví dụ sau đây về SpecifyMessage policy sử dụng thẻ <Payload>, <StatusCode><ReasonPhase> để xác định phản hồi lỗi tuỳ chỉnh được gửi lại cho ứng dụng về lỗi InvalidApiKey (xem ví dụ trước về FaultRules).

<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>

Nội dung phản hồi này bao gồm:

  • Tải trọng có chứa thông báo lỗi và địa chỉ email để liên hệ với bộ phận hỗ trợ.
  • Mã trạng thái HTTP được trả về trong phản hồi.
  • Cụm từ nguyên nhân, là nội dung mô tả ngắn về lỗi.

Tạo DefaultFaultRule

DefaultFaultRule đóng vai trò là trình xử lý ngoại lệ cho mọi lỗi không được một FaultRule khác xử lý rõ ràng. Nếu điều kiện cho tất cả FaultRules không khớp với lỗi đó thì DefaultFaultRule sẽ xử lý lỗi đó. Bật chế độ xử lý lỗi mặc định bằng cách thêm thẻ <DefaultFaultRule> làm phần tử con của ProxyEndpoint hoặc TargetEndpoint.

Ví dụ: cấu hình TargetEndpoint bên dưới xác định DefaultFaultRule gọi một chính sách có tên là ReturnGenericError:

<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 thường được dùng để trả về một thông báo lỗi chung đối với mọi lỗi không mong muốn, chẳng hạn như một thông báo chứa thông tin liên hệ để hỗ trợ kỹ thuật. Phản hồi mặc định này có mục đích kép là cung cấp thông tin thân thiện với nhà phát triển, đồng thời làm rối các URL phụ trợ hoặc thông tin khác có thể dùng để xâm phạm hệ thống.

Ví dụ: bạn xác định chính sách composeMessage sau để trả về lỗi chung:

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

Đưa phần tử <AlwaysEnforce> vào thẻ <DefaultFaultRule> để thực thi DefaultFaultRule cho mọi lỗi, ngay cả khi một lỗi khác đã được thực thi. DefaultFaultRule luôn là FaultRule cuối cùng cần thực thi:

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

Một cách sử dụng DefaultFaultRule là để xác định loại lỗi xảy ra khi bạn không xác định được lỗi đó. Ví dụ: proxy API của bạn bị lỗi do một lỗi mà bạn không xác định được. Sử dụng DefaultFaultRule để gọi chính sách composeMessage sau. Chính sách này ghi giá trị fault.name vào tiêu đề có tên DefaultFaultHeader trong phản hồi:

<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>

Sau đó, bạn có thể xem tiêu đề trong Công cụ theo dõi cạnh hoặc trong phản hồi để xem nguyên nhân gây ra lỗi.

Thêm tính năng ghi nhật ký thông báo vào PostClientFlow

PostClientFlow là luồng duy nhất thực thi sau khi proxy chuyển sang trạng thái lỗi. Bạn chỉ có thể đính kèm MessageLogging policy vào quy trình này. Quy trình này sẽ được thực thi sau khi phản hồi được gửi lại ứng dụng. Mặc dù việc đính kèm chính sáchMessageLogging vào quy trình này về mặt kỹ thuật không phải là quá trình xử lý lỗi, nhưng bạn có thể sử dụng chính sách này để ghi lại thông tin trong trường hợp xảy ra lỗi. Vì chính sách này được thực thi bất kể proxy thành công hay không thành công, nên bạn có thể đặt các chính sách Ghi nhật ký thông báo vào PostClientFlow và đảm bảo rằng các chính sách này luôn thực thi.

Xử lý các lỗi về chính sách trong quy trình hiện tại

Các ví dụ trình bày cho đến nay đều sử dụng một FaultRule trên ProxyEndpoint hoặc TargetEndpoint để xử lý mọi lỗi về chính sách trong trạng thái lỗi. Nguyên nhân là do giá trị mặc định của phần tử continueOnError của một chính sách là false, nghĩa là khi xảy ra lỗi trong một chính sách, chế độ kiểm soát sẽ được chuyển đến trạng thái lỗi. Khi ở trạng thái lỗi, bạn không thể đưa quyền điều khiển trở lại quy trình thông thường và thường trả về một dạng thông báo lỗi cho ứng dụng gọi.

Tuy nhiên, nếu bạn đặt phần tử continueOnError thành true cho một chính sách, quyền kiểm soát vẫn ở trong luồng hiện tại và chính sách tiếp theo trong quy trình sẽ thực thi sau chính sách gây ra lỗi. Lợi thế của việc xử lý lỗi trong luồng hiện tại là bạn có thể có cách để khôi phục lỗi để hoàn tất quá trình xử lý yêu cầu.

Dưới đây là chính sáchVerifyAPIKey có tên verify-api-key, trong đó phần tử continueOnError được đặt thành true:

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

Nếu khoá API bị thiếu hoặc không hợp lệ thì VerifyAPIKey (chính sách VerifyAPIKey) đặt biến oauthV2.verify-api-key.failed thành true, nhưng quá trình xử lý vẫn tiếp tục theo quy trình hiện tại.

Sau đó, bạn thêm chính sách VerifyAPIKey làm một bước trong PreFlow của ProxyEndpoint:

<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>  

Hãy lưu ý cách bước tiếp theo trong PreFlow sử dụng một điều kiện để kiểm thử xem có lỗi hay không. Nếu xảy ra lỗi trong chính sách VerifAPIKey, thì chính sách có tên là chính sách FaultInFlow sẽ thực thi. Nếu không, chính sách FaultInFlow sẽ bị bỏ qua. Chính sách FaultInFlow có thể thực hiện nhiều việc, chẳng hạn như ghi nhật ký lỗi, cố gắng sửa lỗi hoặc thực hiện một số thao tác khác.

Kích hoạt lỗi bằng chính sách RaiseFault

Bạn có thể sử dụng chính sách RaiseFault bất cứ lúc nào trong một luồng để kích hoạt lỗi. Khi một chính sách RaiseFault thực thi, chính sách này sẽ chấm dứt luồng hiện tại và chuyển quyền kiểm soát sang trạng thái lỗi.

Một công dụng của chính sách RaiseFault là để kiểm thử một điều kiện cụ thể mà chính sách khác có thể không phát hiện được. Trong ví dụ trên, bạn đã thêm một thẻ <Condition> vào thẻ <Step> PreFlow khiến chính sách FaultInFlow thực thi nếu điều kiện được đáp ứng. Nếu FaultInFlow là một chính sách RaiseFault, thì chế độ kiểm soát sẽ chuyển sang trạng thái lỗi. Hoặc bạn có thể chèn một chính sách RaiseFault vào một quy trình để gỡ lỗi và kiểm thử FaultRules.

Khi một chính sách RaiseFault kích hoạt lỗi, bạn có thể sử dụng FaultRule và điều kiện sau đây để xử lý lỗi:

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

Xin lưu ý rằng điều kiện này sẽ kiểm thử lỗi có tên RaiseFault. Chính sách RaiseFault luôn đặt giá trị của fault.name thành RaiseFault.

Xử lý tuỳ chỉnh mã lỗi HTTP từ máy chủ mục tiêu

Ví dụ trong các phần trước áp dụng cho các lỗi do chính sách tạo ra. Tuy nhiên, bạn cũng có thể tạo phản hồi tuỳ chỉnh cho các lỗi ở cấp độ truyền tải, nghĩa là các lỗi HTTP do máy chủ mục tiêu trả về. Để kiểm soát hoạt động phản hồi từ một lỗi HTTP, hãy định cấu hình TargetEndpoint để xử lý mã phản hồi HTTP.

Theo mặc định, Edge coi các mã phản hồi HTTP trong phạm vi 1xx-3xx là "thành công", còn các mã phản hồi HTTP trong phạm vi 4xx-5xx là "thất bại". Tức là mọi phản hồi của dịch vụ phụ trợ có mã phản hồi HTTP 4xx-5xx sẽ tự động gọi trạng thái lỗi, sau đó trực tiếp trả về thông báo lỗi cho ứng dụng yêu cầu.

Bạn có thể tạo trình xử lý tuỳ chỉnh cho bất kỳ mã phản hồi HTTP nào. Ví dụ: có thể bạn không muốn coi tất cả các mã phản hồi HTTP trong khoảng 4xx-5xx là "thất bại" mà chỉ cần 5xx hoặc trả về thông báo lỗi tuỳ chỉnh cho các mã phản hồi HTTP 400 và 500.

Trong ví dụ tiếp theo, bạn sử dụng thuộc tính success.codes để định cấu hình TargetEndpoint nhằm xem mã phản hồi HTTP 400 và 500 là thành công, cùng với các mã HTTP mặc định. Bằng cách coi các mã đó là thành công, TargetEndpoint sẽ tiếp quản quá trình xử lý thông báo phản hồi, thay vì gọi trạng thái lỗi:

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

Như có thể thấy trong ví dụ này, bạn có thể sử dụng ký tự đại diện để đặt thuộc tính success.codes vào một phạm vi các giá trị.

Việc đặt thuộc tính success.codes sẽ ghi đè các giá trị mặc định. Do đó, nếu bạn muốn thêm mã HTTP 400 vào danh sách mã thành công mặc định, hãy đặt thuộc tính này là:

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

Tuy nhiên, nếu bạn chỉ muốn mã HTTP 400 được coi là mã thành công, hãy đặt thuộc tính là:

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

Giờ đây, bạn có thể xác định các trình xử lý tuỳ chỉnh cho các mã phản hồi HTTP 400 và 500 để trả về một thông báo phản hồi tuỳ chỉnh cho ứng dụng yêu cầu. TargetEndpoint sau đây sử dụng chính sách có tên ReturnError để xử lý các mã phản hồi HTTP 400 và 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>

Cấu hình TargetEndpoint này khiến chính sách có tên là ReturnError xử lý phản hồi bất cứ khi nào TargetEndpoint gặp phải mã phản hồi HTTP 400 hoặc 500.

Hệ thống phân loại lỗi

Dịch vụ API sắp xếp các lỗi thành các danh mục và danh mục phụ sau đây.

Danh mục Danh mục con Tên lỗi Nội dung mô tả
Nhắn tin Các lỗi xảy ra trong luồng thông báo (không bao gồm lỗi về chính sách)
Lỗi tuỳ chỉnh {fault_name} Mọi lỗi được proxy API xử lý rõ ràng bằng chính sách RaiseFault
Mã phản hồi Lỗi máy chủ nội bộ, Không tìm thấy Mã lỗi HTTP 5xx, 4xx
Lỗi định tuyến NoRoutesMatched Không thể chọn TargetEndpoint được đặt tên cho một yêu cầu
Lỗi phân loại NotFound Lỗi do một URI yêu cầu không khớp với bất kỳ BasePath nào cho bất kỳ cấu hình ProxyEndpoint nào (nghĩa là không có proxy API nào khớp với URL trong yêu cầu của ứng dụng khách)
Di chuyển Lỗi cấp truyền tải HTTP
Khả năng kết nối Kết nối bị từ chối, Kết nối được đặt lại, Thời gian chờ kết nối Lỗi xảy ra khi thiết lập kết nối cấp mạng hoặc cấp truyền tải
Yêu cầu xác thực Thiếu ContentLength, HostHeader Thiếu Lỗi xảy ra trong quá trình kiểm tra ngữ nghĩa đối với mọi yêu cầu
Xác thực phản hồi Lỗi xảy ra trong quá trình kiểm tra ngữ nghĩa trên mọi phản hồi
Lỗi IO SSLhandkingError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError Đọc/ghi lỗi tại điểm cuối của ứng dụng hoặc điểm cuối đích, hết thời gian chờ, lỗi TLS/SSL và lỗi phân đoạn
Hệ thống Lỗi thời gian chạy không xác định
Bộ nhớ OutOfMemory, GCOverLimit Lỗi liên quan đến bộ nhớ
Chuỗi hội thoại RogueTaskTerminated Lỗi, chẳng hạn như chấm dứt nhiệm vụ chạy thoát
Chính sách Các lỗi của từng loại chính sách được xác định trong Tài liệu tham khảo về chính sách.

Lỗi luôn đi kèm với phần mô tả bằng văn bản về lý do không đạt. Khi hệ thống đưa ra lỗi, một nhóm các thuộc tính sẽ được điền sẵn để hỗ trợ khắc phục sự cố. Lỗi bao gồm những thông tin sau:

  • Lý do
  • Thuộc tính tuỳ chỉnh do người dùng xác định