Xử lý lỗi

Bạn đang xem tài liệu về Apigee Edge.
Truy cập vào tài liệu Apigee X.
Thông tin

Nhiều điều kiện lỗi có thể xảy ra trong khi các proxy API đang xử lý các yêu cầu từ ứng dụng. Ví dụ: các proxy API có thể gặp phải vấn đề về mạng khi giao tiếp với các dịch vụ phụ trợ, các ứng dụng có thể trình bày 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 một ứng dụng khách gọi một proxy API, một thông báo lỗi sẽ được trả về cho ứng dụng khách. Theo mặc định, ứng dụng sẽ nhận được một thông báo lỗi thường khó hiểu mà không có thông tin chi tiết hoặc hướng dẫn. Nhưng nếu muốn thay thế thông báo lỗi mặc định bằng thông báo tuỳ chỉnh hữu ích hơn, thậm chí làm phong phú thông báo bằng những nội dung như tiêu đề HTTP bổ sung, bạn cần thiết lập cơ chế xử lý lỗi tuỳ chỉnh trong Edge.

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

Trước khi thảo luận về cách triển khai tính năng xử lý lỗi tuỳ chỉnh trong các proxy API, bạn nên tìm 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 Mô tả
Giới thiệu về quy trình xử lý lỗi và lỗi Tìm hiểu về cách xử lý lỗi và những gì xảy ra khi có lỗi trong một proxy API.
Xử lý lỗi bằng quy tắc lỗi Tìm hiểu cách xử lý lỗi bằng quy tắc lỗi.
Đưa ra lỗi tuỳ chỉnh bằng cách sử dụng chính sách RaiseFault Đưa ra các 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 mục tiêu, đồng thời nắm được sự khác biệt.
Tìm hiểu thứ tự thực thi của các quy tắc lỗi Tìm hiểu thứ tự thực thi của các quy tắc lỗi trong proxy API và các điểm cuối 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ủa bạn.

Cách xảy ra lỗi

Trước tiên, chúng ta sẽ chỉ đề cập đến cách xảy ra lỗi. Khi biết cách xảy ra lỗi, bạn có thể lên kế hoạch cho các tình huống mà bạn muốn triển khai quy trình xử lý lỗi tuỳ chỉnh.

Lỗi tự động

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

  • Một chính sách báo 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ách VerifyAPIKey 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 Chống đột biến 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ể đưa ra).
  • Đã xảy ra vấn đề trong luồng thông báo của 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 hoạt động.
  • Đã xảy ra lỗi ở cấp hệ thống, chẳng hạn như trường hợp ngoại lệ hết bộ nhớ.

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

Lỗi tuỳ chỉnh

Đối với những trường hợp không có lỗi tự động, bạn có thể muốn đưa ra một lỗi tuỳ chỉnh; ví dụ: nếu một phản hồi chứa từ "không có sẵn" 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 chính sách RaiseFault vào vị trí thích hợp trong một luồng proxy API.

Bạn có thể thêm chính sách RaiseFault vào một luồng proxy API giống như cách bạn thực hiện với 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ào phản hồi TargetEndpoint. Nếu từ "unavailable" xuất hiện trong phản hồi của dịch vụ đích, thì chính sách RaiseFault sẽ được thực thi và đưa ra lỗi.

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

Đây chỉ là để cho bạn thấy rằng bạn có thể đưa ra các lỗi tuỳ chỉnh. Chúng tôi trình bày chi tiết hơn về chính sách RaiseFault trong phần FaultRules so với chính sách RaiseFault.

Để xem thêm ví dụ, hãy xem những bài đăng này trên Diễn đàn cộng đồng Apigee:

Những việc mà các proxy API thực hiện khi xảy ra lỗi

Sau đây là những điều sẽ xảy ra khi một proxy gặp lỗi.

Thoát khỏi quy trình proxy

Khi gặp lỗi, bất kể lỗi đó xảy ra như thế nào, proxy API sẽ thoát khỏi pipeline 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 chuyển sang trạng thái lỗi, proxy API không thể trả lại quy trình xử lý cho pipeline luồng thông thường.

Ví dụ: giả sử một API proxy có các chính sách theo thứ tự sau 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, thì proxy API sẽ chuyển sang trạng thái lỗi. Chính sách Hạn mức và JSON sang XML không được thực thi, proxy không chuyển sang TargetEndpoint và một thông báo lỗi được trả về cho ứng dụng khách.

Kiểm tra FaultRules

Ở trạng thái lỗi, các proxy API cũng kiểm tra sự hiện diện của những nội dung 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 khách:

  1. Một phần <FaultRules> chứa logic để kích hoạt thông báo lỗi tuỳ chỉnh (và các chính sách khác) dựa trên các điều kiện cụ thể mà bạn xác định.
  2. Một phần <DefaultFaultRule>, 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 có nào được thực thi.
    • Phần tử <AlwaysEnforce> được đặt thành true.

Về cơ bản, proxy API mang đến 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 không tìm thấy cả hai phần đó hoặc chúng 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.

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

Hãy bắt đầu bằng một ví dụ đơn giản, trong đó một 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ề cho ứ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ể hiểu được thông báo lỗi, nhưng cũng có thể không. Và nhiều lỗi mặc định tinh vi hơn và khó giải mã hơn.

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

Sau đây là ví dụ cơ bản về cách tạo thông báo lỗi tuỳ chỉnh để xử lý lỗi này. Việc này yêu cầu 1) một 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 một 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ư chính sách AssignMessage, có thể đặt tải trọng và tiêu đề HTTP không bắt buộc, chẳng hạn như mã trạng thái và cụm từ lý do. Tính năng Giao tin nhắn là lựa chọn lý tưởng cho trường hợp này. Bạn có thể kiểm soát tải trọng thông báo, đặt mã trạng thái HTTP khác, đặt cụm từ lý do HTTP khác và thêm tiêu đề HTTP.

Đừng đính kèm chính sách vào bất kỳ luồng 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ẻ Develop (Phát triển), rồi trong ngăn Navigation (Điều hướng), hãy nhấp vào biểu tượng + trên thanh Policies (Chính sách).

Nhờ đó, bạn có thể 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. Một chính sách không được đính kèm vào bất kỳ luồng nào sẽ được gắn cờ bằng biểu tượng "đã tách" trong danh sách Chính sách, như minh hoạ bên cạnh chính sách thông báo khoá API trong hình trước.

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

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

Có thể hơi ngớ ngẩn, nhưng ví dụ này cho thấy những gì bạn có thể làm. Ít nhất thì giờ đây, nhà phát triển nhận được thông báo sẽ biết rằng họ quên thêm khoá API làm tham số truy vấn.

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

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

Trong phần <ProxyEndpoint> hoặc <TargetEndpoint> của cấu hình proxy, bạn sẽ thêm một khối <FaultRules> XML 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 mà bạn muốn xử lý. Trong ví dụ đơn giản này, chúng ta sẽ chỉ sử dụng một FaultRule để cho bạn biết FaultRule bao gồm những gì.

Bạn cũng nên thêm một <DefaultFaultRule> để cung cấp thông báo lỗi chung tuỳ chỉnh nếu không có FaultRule 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. Tìm hiểu thêm về cách đặt FaultRules trong ProxyEndpoint so với TargetEndpoint sau.
  • <Name> – Tên của chính sách cần thực thi. Tên này lấy từ thuộc tính name của chính sách trên phần tử mẹ, như minh hoạ 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 đó đúng. Nếu có nhiều FaultRule đánh giá là đúng, thì Edge sẽ thực thi FaultRule đầu tiên là đúng. (Lưu ý quan trọng: Thứ tự đánh giá FaultRule (từ trên xuống hoặc từ dưới lên) khác nhau giữa TargetEndpoint và ProxyEndpoint, như mô tả trong phần Nhiều FaultRule và logic thực thi.) Nếu bạn không thêm điều kiện, FaultRule sẽ tự động là true. Nhưng đó không phải là phương pháp hay nhất. Mỗi FaultRule phải có đ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, gửi một thông báo tuỳ chỉnh chung chung hơn thay vì thông báo mặc định khó hiểu do Edge tạo. <DefaultFaultRule> cũng có thể có một <Condition>, nhưng trong hầu hết các trường hợp, bạn sẽ không thêm <Condition> vì bạn muốn <DefaultFaultRule> thực thi bất kể điều gì như một phương sách cuối cùng.

    DefaultFaultRule thường được dùng để trả về thông báo lỗi chung cho mọi lỗi không mong muốn. Ví dụ: một thông báo có 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ó hai mục đích: cung cấp thông tin thân thiện với nhà phát triển, đồng thời che giấu các URL phụ trợ hoặc thông tin khác có thể được dùng để xâm nhập hệ thống.

Nhiều FaultRule và logic thực thi

Trong phần Ví dụ đơn giản về xử lý lỗi, chúng ta đã 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ể có nhiều FaultRule và một DefaultFaultRule trong cả <ProxyEndpoint><TargetEndpoint>. Tuy nhiên, cuối cùng, chỉ có một FaultRule được thực thi khi một proxy API chuyển sang trạng thái lỗi.

Phần này mô tả logic mà Edge sử dụng trong việc xử lý FaultRules, từ cách Edge đưa ra một FaultRule duy nhất để thực thi đến cách xử lý các điều kiện "bên trong" của Bước khi FaultRule của chúng được kích hoạt. Phần này cũng cung cấp 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. Lưu ý rằng có một chút khác biệt 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 vị trí xảy ra lỗi:
    • ProxyEndpoint – Edge bắt đầu bằng phần dưới cùng <FaultRule> trong cấu hình XML và hoạt động theo cách riêng, đánh giá <Condition> của mỗi <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 bằng top <FaultRule> trong tệp cấu hình XML và hoạt động theo cách riêng, đánh giá <Condition> của mỗi <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 là đúng. Nếu FaultRule không có điều kiện, thì theo mặc định, điều kiện đó sẽ là true.
    • Khi 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 tự động thực thi (các chính sách đượ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 FaultRule được thực thi nhưng không có Bước nào trong FaultRule được thực thi (vì các điều kiện của chúng đánh giá là "false"), thì thông báo lỗi mặc định do Edge tạo sẽ được trả về cho ứng dụng khách. <DefaultFaultRule> sẽ 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à ví dụ về nhận xét trong dòng.

Thực thi ProxyEndpoint

Việc đánh giá FaultRule của ProxyEndpoint diễn ra từ dưới lên, vì vậy, hãy bắt đầu đọc từ FaultRule cuối cùng trong mẫu sau và đọc ngược lên. Xem DefaultFaultRule sau 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

Việc đánh giá TargetEndpoint FaultRules diễn ra từ trên xuống dưới, vì vậy, hãy bắt đầu đọc từ FaultRule đầu tiên trong mẫu sau và đọc xuống dưới. Xem DefaultFaultRule sau 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ự mà bạn đặt FaultRules là quan trọng tuỳ thuộc vào việc lỗi xảy ra trong ProxyEndpoint hay TargetEndpoint.

Ví dụ:

Thứ tự ProxyEndpoint Thứ tự TargetEndpoint

Trong ví dụ sau, vì quá trình đánh giá diễn ra từ dưới lên, nên FaultRule 3 sẽ được thực thi, tức là FaultRule 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 SAI

Trong ví dụ sau, vì quá trình đánh giá diễn ra từ trên xuống dưới, nên FaultRule 2 sẽ được thực thi, nghĩa là FaultRule 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 SAI

Các chính sách cần thêm

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

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

Tiêu đề này có vẻ như chúng tôi đang lặp lại chính mình, nhưng có một sắc thái cụ thể cần lưu ý liên quan đến lỗi proxy khiến proxy API chuyển sang trạng thái lỗi – hay đúng hơn là không chuyển sang trạng thái lỗi: thuộc tính continueOnError trên một 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 điều kiện FaultRule đánh giá là true, điều kiệ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. Đối với mọi chính sách, bạn 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 xác định xem proxy có chuyển sang trạng thái lỗi hay không nếu chính sách không thành công. Trong hầu hết các trường hợp, bạn nên giữ lại continueOnError="false" mặc định. Lựa chọn này sẽ đặt proxy ở trạng thái lỗi nếu chính sách 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 việc không thực hiện được Lời gọi dịch vụ sẽ dừng quá trình thực thi proxy), thì 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 xét FaultRules của bạn.

Để biết thông tin về cách ghi nhật ký 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 từ hoặc phản hồi cho ứng dụng khách) hoặc trong <TargetEndpoint> (yêu cầu đến hoặc phản hồi từ dịch vụ đích). Bất cứ nơi nào xảy ra lỗi đó, Edge sẽ tìm FaultRules.

Ví dụ: nếu máy chủ đích không hoạt động (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 một chính sách RaiseFault trên phản hồi <ProxyEndpoint> kích hoạt lỗi, thì FaultRule trong <TargetEndpoint> sẽ không được thực thi.

FaultRules so với chính sách RaiseFault

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

Tóm lại:

  • 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 một proxy API ở trạng thái lỗi khi lỗi không xảy ra.

    Ví dụ: nếu bạn muốn gửi một lỗi nếu mã trạng thái HTTP trong phản hồi từ dịch vụ đích lớn hơn 200, hãy thêm một chính sách RaiseFault vào luồng phản hồi của bạn. 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 lỗi, khiến proxy chuyển sang trạng thái lỗi, có khả năng thực thi FaultRule? Đây là lúc mọi thứ có thể trở nên hơi phức tạp. Nếu chính sách RaiseFault trả về thông báo lỗi FaultRule được kích hoạt và trả về thông báo lỗi, thì thông báo nào sẽ được trả về cho ứ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ẽ được ưu tiên.
  • Dữ liệu phản hồi 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 dùng nếu dữ liệu đó không được đặt theo 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 đề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ị.

Sau đây là ví dụ về những gì được đặt theo chính sách RaiseFault và FaultRule, cũng như những gì được trả về cho ứng dụng khách. Các mẫu này được thiết kế ngắn gọn chứ không phải theo 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

<- Fault rules policy sets this:

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

<- Chính sách RaiseFault đặt giá trị 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à chìa khoá để thực thi FaultRule. Bạn tạo các điều kiện FaultRule theo cách tương tự như cách bạn tạo các điều kiện khác trong Edge, chẳng hạn như đối với các điều kiện RaiseFault hoặc luồng có điều kiện.

Để đặt phần còn lại của phần này trong ngữ cảnh, sau đây là một quy tắc lỗi mẫu có điều kiện FaultRule bên ngoài và điều kiện Step 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 dành riêng cho lỗi vi phạm chính sách

Các biến fault.name{policy_namespace}.{policy_name}.failed có sẵn khi một chính sách gửi lỗi.

fault.name

Khi một chính sách không thành công, hãy bắt 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 phần 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 đượ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ẽ có dạng như sau:

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

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

{policy_namespace}.{policy_name}.failed

Biến *.failed sẽ có sẵn khi một chính sách không thành công. Sau đây là ví dụ về các biến *.failed cho các chính sách khác nhau. Đối với không gian tên chính sách, hãy xem các biến luồng trong từng chủ đề tài liệu tham khảo về 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ể dùng trong đ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 xảy ra lỗi. Ví dụ: nếu một lỗi được đưa 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 hạn mức không thành công, bạn có thể sử dụng biến ratelimit.{quota_policy_name}.exceed.count. Hãy sử dụng Công cụ theo dõicác chủ đề tham khảo về chính sách để giúp bạn tìm ra những biến số 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 nội dung của thông báo lỗi và thiết kế định dạng thông báo lỗi. Sau khi (hoặc trong 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 để hỗ trợ bạn triển khai tính năng xử lý lỗi.

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

  • Đối với mỗi FaultRule, hãy cung cấp một <Condition> "bên ngoài" (cù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à đúng. Điều kiện của bước "Nội bộ" không được dùng để xác định xem FaultRule là đúng hay sai. Các điều kiện của bước chỉ được đánh giá sau khi Edge thực thi FaultRule chứa các điều kiện đó. Trong FaultRule, thông thường sẽ có nhiều Bước với các chính sách Gán thông báo (hoặc chính sách khác), mỗi bước có một điều kiện Bước.
  • Để xử lý lỗi trong nhiều chính sách cùng loại (ví dụ: nhiều chính sách Hạn ngạch), hãy tạo một FaultRule cho mỗi lỗi chính sách mà bạn có thể nhận được. Ví dụ: tạo một FaultRule cho mỗi lỗi có thể xảy ra trong chính sách Hạn mức, chẳng hạn như QuotaViolation, InvalidMessageWeight, StartTimeNotSupported. (Hãy xem Tài liệu tham khảo về lỗi vi phạm chính sách để biết các lỗi vi phạm chính sách. Khi phát hiện thêm các lỗi 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 quy trình này, 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 gây ra lỗi đó, giúp XML FaultRules của bạn hoạt động 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 cho từng nhà phát triển và hạn mức chung bằng hai chính sách trong luồng yêu cầu, hãy đặt điều kiện FaultRule "bên ngoài" để được kích hoạt khi xảy ra lỗi QuotaViolation (lỗi này sẽ xuất hiện khi hạn mức vượt quá trong cả hai trường hợp). Sau đó, hãy đặt các đ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 đến ứng dụng (vượt quá hạn mức của nhà phát triển hoặc vượt quá hạn mức chung). Sau đây là một 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>

    Để xem một ví dụ khác, hãy xem chuỗi bài đăng này trên Cộng đồng Apigee.

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

Mẫu để xử lý lỗi tập trung, có thể sử dụng lại

Bài đăng sau đây trên Cộng đồng Apigee mô tả một mẫu để xử lý lỗi tập trung mà không cần sao chép mã:

Mẫu xử lý lỗi cho các proxy Apigee

Tạo FaultRule

Để thêm 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 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ố gắng lưu một 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ù có thể đặt bất kỳ chính sách nào trong FaultRule, nhưng bạn thường dùng chính sách AssignMessage để tạo thông báo phản hồi tuỳ chỉnh cho một điều kiện lỗi. AssignMessage cho phép bạn định cấu hình một phản hồi HTTP có 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 cho thấy cấu hình chính sách AssignMessage điển hình:

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

Giờ đây, bạn có thể sử dụng chính sách này trong FaultRule. Lưu ý cách bạn tham chiếu chính sách AssignMessage 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 AssignMessage có tên là fault_invalidkey bất cứ khi nào một ứng dụng xuất hiện khoá 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ách MessageLogging, chính sách ExtractVariables, chính sách AssignMessage 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 hai trường hợp sau xảy ra:

  • Mọi chính sách trong FaultRule đều gây ra lỗi
  • Bất kỳ chính sách nào 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 rõ các phản hồi lỗi từ API của mình. Bằng cách đó, bạn sẽ cung cấp thông tin nhất quán và hữu ích cho khách hàng.

Ví dụ về chính sách AssignMessage sau đây sử dụng các thẻ <Payload>, <StatusCode><ReasonPhase> để xác định phản hồi lỗi tuỳ chỉnh được gửi lại cho máy khách khi xảy ra 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>

Câu trả lời này bao gồm:

  • Tải trọng 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ừ lý do, là nội dung mô tả ngắn gọn về lỗi.

Tạo DefaultFaultRule

DefaultFaultRule hoạt động như một trình xử lý ngoại lệ cho mọi lỗi không được FaultRule khác xử lý một cách rõ ràng. Nếu các điều kiện cho tất cả FaultRule không khớp với lỗi, thì DefaultFaultRule sẽ xử lý lỗi. Bật tính năng 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 một 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 cho 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ệ để được hỗ trợ kỹ thuật. Phản hồi mặc định này có hai mục đích: cung cấp thông tin thân thiện với nhà phát triển, đồng thời che giấu các URL phụ trợ hoặc thông tin khác có thể được dùng để xâm nhập hệ thống.

Ví dụ: bạn xác định chính sách AssignMessage sau đây để trả về một lỗi chung:

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

Thêm phần tử <AlwaysEnforce> vào thẻ <DefaultFaultRule> để thực thi DefaultFaultRule cho mọi lỗi, ngay cả khi một FaultRule 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 thể xác định được loại lỗi đó. Ví dụ: proxy API của bạn đang gặp lỗi mà bạn không thể xác định. Sử dụng DefaultFaultRule để gọi chính sách AssignMessage sau. Chính sách này ghi giá trị fault.name vào một 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 Edge hoặc trên phản hồi để biết 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. Chỉ có thể đính kèm chính sách MessageLogging vào luồng này. Chính sách này sẽ được thực thi sau khi phản hồi được gửi lại cho ứng dụng khách. Mặc dù việc đính kèm chính sách MessageLogging vào luồng này không phải là xử lý lỗi về mặt kỹ thuật, nhưng bạn có thể dùng chính sách này để ghi nhật ký 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 có thành công hay không, bạn có thể đặt các chính sách Ghi nhật ký thông báo trong PostClientFlow và đảm bảo rằng các chính sách này luôn được thực thi.

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

Tất cả các ví dụ đã trình bày cho đến nay đều sử dụng FaultRule trên ProxyEndpoint hoặc TargetEndpoint để xử lý mọi lỗi chính sách trong trạng thái lỗi. Đó là do giá trị mặc định của phần tử continueOnError trong một chính sách là false, tức là khi xảy ra lỗi trong một chính sách, quyền 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ể trả quyền kiểm soát về quy trình thông thường và thường trả về một dạng thông báo lỗi nào đó 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, thì quyền kiểm soát vẫn nằm 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 ích của việc xử lý lỗi trong quy trình hiện tại là bạn có thể có cách khắc phục lỗi để hoàn tất quá trình xử lý yêu cầu.

Dưới đây là chính sách VerifyAPIKey có tên là verify-api-key với 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ì chính sách VerifyAPIKey sẽ đặt biến oauthV2.verify-api-key.failed thành true, nhưng quá trình xử lý vẫn tiếp tục trong luồng 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>

Lưu ý cách bước tiếp theo trong PreFlow sử dụng một điều kiện để kiểm tra sự tồn tại của lỗi. 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ể làm nhiều việc, chẳng hạn như ghi nhật ký lỗi, cố gắng khắc phục lỗi hoặc thực hiện một số hành động khác.

Kích hoạt lỗi bằng cách sử dụ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 chính sách RaiseFault thực thi, chính sách này sẽ chấm dứt quy trình hiện tại và chuyển quyền kiểm soát sang trạng thái lỗi.

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

Khi 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 để xử lý lỗi đó:

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

Lưu ý rằng điều kiện kiểm thử cho một lỗi có tên là 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ủ đích

Các ví dụ được trình bày trong các phần trước áp dụng cho lỗi do chính sách tạo ra. Tuy nhiên, bạn cũng có thể tạo một phản hồi tuỳ chỉnh cho các lỗi ở cấp độ truyền tải, tức là các lỗi HTTP được trả về từ máy chủ đích. Để kiểm soát 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 mã phản hồi HTTP trong dải 1xx – 3xx là "thành công" và mã phản hồi HTTP trong dải 4xx – 5xx là "thất bại". Điều đó có nghĩa là mọi phản hồi từ dịch vụ phụ trợ có mã phản hồi HTTP 4xx-5xx sẽ tự động kích hoạt trạng thái lỗi, sau đó trả về trực tiếp một thông báo lỗi cho ứng dụng khách yêu cầu.

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

Trong ví dụ tiếp theo, bạn sẽ sử dụng thuộc tính success.codes để định cấu hình TargetEndpoint nhằm xử lý 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 nhận việc 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ư bạn 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 thành một dải 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 như sau:

<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 như sau:

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

Giờ đây, bạn có thể xác định trình xử lý tuỳ chỉnh cho 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 là ReturnError để xử lý 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 ReturnError xử lý phản hồi bất cứ khi nào TargetEndpoint gặp mã phản hồi HTTP là 400 hoặc 500.

Phân loại lỗi

API Services sắp xếp các lỗi thành các danh mục và danh mục con sau đây.

Danh mục Danh mục con Tên lỗi Mô tả
Nhắn tin Lỗi xảy ra trong quá trình truyền thông báo (không bao gồm lỗi vi phạm chính sách)
Lỗi tuỳ chỉnh {fault_name} Mọi lỗi được xử lý rõ ràng bằng proxy API bằng chính sách RaiseFault
Mã phản hồi InternalServerError, NotFound Mã lỗi HTTP 5xx, 4xx
Lỗi định tuyến NoRoutesMatched Không chọn được TargetEndpoint có tên cho một yêu cầu
Lỗi phân loại NotFound Lỗi do URI yêu cầu không khớp với BasePath nào cho bất kỳ cấu hình ProxyEndpoint nào (tức là không có API proxy nào khớp với URL trong yêu cầu của ứng dụng khách)
Giao thông vận tải Lỗi ở cấp truyền tải HTTP
Khả năng kết nối ConnectionRefused, ConnectionReset, ConnectionTimeout Lỗi xảy ra trong khi thiết lập kết nối mạng hoặc kết nối ở cấp độ truyền tải
Yêu cầu xác thực ContentLengthMissing, HostHeaderMissing Lỗi xảy ra trong quá trình kiểm tra ngữ nghĩa trên 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 SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError Lỗi đọc/ghi tại điểm cuối của ứng dụng hoặc mục tiêu, thời gian chờ, lỗi TLS/SSL và lỗi theo khối
Hệ thống Lỗi không xác định về thời gian chạy
Bộ nhớ OutOfMemory, GCOverLimit Lỗi liên quan đến bộ nhớ
Chuỗi hội thoại RogueTaskTerminated Các lỗi như chấm dứt các tác vụ không kiểm soát được
Policy Các lỗi cho 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 nội dung mô tả bằng văn bản về lý do khiến yêu cầu không thành công. Khi hệ thống gặp lỗi, một nhóm 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