رسیدگی به عیوب

شما در حال مشاهده مستندات Apigee Edge هستید.
به مستندات Apigee X مراجعه کنید .
اطلاعات

بسیاری از شرایط خطا ممکن است هنگام سرویس‌دهی به درخواست‌های برنامه‌ها توسط پروکسی‌های API ایجاد شوند. به عنوان مثال، پروکسی‌های API ممکن است هنگام برقراری ارتباط با سرویس‌های backend با مشکلات شبکه مواجه شوند، برنامه‌ها ممکن است اعتبارنامه‌های منقضی شده ارائه دهند، پیام‌های درخواست ممکن است به طور نادرست قالب‌بندی شده باشند و غیره.

وقتی خطایی پس از فراخوانی یک پروکسی API توسط برنامه کلاینت رخ می‌دهد، یک پیام خطا به کلاینت بازگردانده می‌شود. به طور پیش‌فرض، کلاینت یک پیام خطای اغلب مبهم و بدون جزئیات یا راهنمایی دریافت می‌کند. اما اگر می‌خواهید پیام‌های خطای پیش‌فرض را با پیام‌های سفارشی مفیدتر جایگزین کنید و حتی آنها را با چیزهایی مانند هدرهای HTTP اضافی غنی کنید، باید مدیریت خطای سفارشی را در Edge تنظیم کنید.

مدیریت خطای سفارشی همچنین به شما امکان می‌دهد قابلیت‌هایی مانند ثبت پیام در صورت بروز خطا را اضافه کنید.

قبل از اینکه در مورد پیاده‌سازی مدیریت خطای سفارشی در پروکسی‌های API شما صحبت کنیم، درک چگونگی رخ دادن خطاها و نحوه واکنش پروکسی‌های API به آنها مفید است.

ویدیوها

برای آشنایی بیشتر با نحوه‌ی مدیریت خطا، ویدیوهای زیر را تماشا کنید.

ویدئو توضیحات
مقدمه‌ای بر مدیریت خطا و جریان‌های خطا در مورد مدیریت خطا و اینکه هنگام بروز خطا در یک پروکسی API چه اتفاقی می‌افتد، اطلاعات کسب کنید.
مدیریت خطاها با استفاده از قوانین خطا یاد بگیرید که چگونه با استفاده از قوانین خطا، خطاها را مدیریت کنید.
با استفاده از سیاست RaiseFault، خطاهای سفارشی را ایجاد کنید با استفاده از سیاست RaiseFault، خطاهای سفارشی را در طول زمان اجرای API ایجاد کنید.
تعریف قوانین خطا در پروکسی API و نقاط انتهایی هدف قوانین خطا را در پروکسی API و نقاط انتهایی هدف تعریف کنید و تفاوت‌ها را درک کنید.
ترتیب اجرای قوانین خطا را درک کنید ترتیب اجرای قوانین خطا در پروکسی API و نقاط انتهایی هدف را درک کنید.
تعریف قانون خطای پیش‌فرض برای مدیریت خطاهای عمومی در API خود، قانون خطای پیش‌فرض تعریف کنید.

نحوه بروز خطاها

ابتدا به طور خلاصه نحوه‌ی رخ دادن خطاها را بررسی می‌کنیم. دانستن نحوه‌ی رخ دادن خطاها به شما کمک می‌کند تا برای موقعیت‌های مختلفی که می‌خواهید مدیریت خطای سفارشی را پیاده‌سازی کنید، برنامه‌ریزی کنید.

خطاهای خودکار

یک پروکسی API در شرایط زیر به طور خودکار خطا می‌دهد:

  • یک سیاست خطا می‌دهد. برای مثال، اگر یک فراخوانی API یک کلید منقضی شده ارسال کند، سیاست VerifyAPIKey به طور خودکار خطا می‌دهد؛ یا اگر تعداد فراخوانی‌های API از حد مشخصی فراتر رود، سیاست Quota یا سیاست SpikeArrest خطا می‌دهد. (برای انواع خطاهایی که سیاست‌ها می‌توانند ایجاد کنند، به مرجع خطای سیاست مراجعه کنید).
  • مشکلی در جریان پیام پروکسی API وجود دارد، مانند خطای مسیریابی.
  • یک خطای backend وجود دارد، مانند خطای HTTP به دلیل خرابی سطح پروتکل، خطاهای TLS/SSL یا عدم دسترسی به سرویس هدف.
  • یک خرابی در سطح سیستم وجود دارد، مانند خطای کمبود حافظه.

برای اطلاعات بیشتر در مورد این خطاها، به طبقه‌بندی خطا در این مبحث مراجعه کنید.

خطاهای سفارشی

برای موقعیت‌هایی که خطای خودکار وجود ندارد، می‌توانید یک خطای سفارشی ایجاد کنید؛ برای مثال، اگر پاسخی حاوی کلمه "unavailable" باشد، یا اگر کد وضعیت HTTP بزرگتر از 201 باشد. این کار را با اضافه کردن یک سیاست RaiseFault به مکان مناسب در جریان پروکسی API انجام دهید.

شما می‌توانید یک سیاست RaiseFault را مانند هر سیاست دیگری به جریان پروکسی API اضافه کنید. در مثال پیکربندی پروکسی زیر، سیاست Raise-Fault-1 به پاسخ TargetEndpoint پیوست شده است. اگر کلمه "unavailable" در پاسخ سرویس هدف وجود داشته باشد، سیاست RaiseFault اجرا شده و خطا می‌دهد.

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

این فقط برای نشان دادن این است که می‌توانید خطاهای سفارشی ایجاد کنید. ما در بخش «مقایسه‌ی سیاست FaultRules با سیاست RaiseFault» به جزئیات بیشتری در مورد سیاست RaiseFault می‌پردازیم.

برای مثال‌های بیشتر، به این پست‌ها در انجمن‌های Apigee Community مراجعه کنید:

کاری که پروکسی‌های API هنگام بروز خطا انجام می‌دهند

در اینجا اتفاقی که هنگام بروز خطا توسط پروکسی رخ می‌دهد را مشاهده می‌کنید.

از خط لوله پروکسی خارج شوید

وقتی یک پروکسی API با خطایی مواجه می‌شود، صرف نظر از نحوه‌ی وقوع آن، از خط لوله‌ی جریان عادی خارج می‌شود، وارد حالت خطا می‌شود و یک پیام خطا به برنامه‌ی کلاینت برمی‌گرداند. به محض اینکه پروکسی API وارد حالت خطا شود، نمی‌تواند پردازش را به خط لوله‌ی جریان عادی بازگرداند.

برای مثال، فرض کنید یک پروکسی API در درخواست ProxyEndpoint دارای سیاست‌هایی به ترتیب زیر است:

  1. کلید API را تأیید کنید
  2. سهمیه
  3. تبدیل JSON به XML

اگر در حین تأیید کلید API خطایی رخ دهد، پروکسی API به حالت خطا می‌رود. سیاست‌های Quota و JSON to XML اجرا نمی‌شوند، پروکسی به TargetEndpoint نمی‌رود و یک پیام خطا به برنامه کلاینت برگردانده می‌شود.

بررسی قوانین خطا (FaultRules)

در حالت خطا، پروکسی‌های API قبل از بازگرداندن پیام خطای پیش‌فرض به برنامه‌ی کلاینت، وجود موارد زیر (به ترتیب) را در پیکربندی پروکسی API نیز بررسی می‌کنند:

  1. یک بخش <FaultRules> که شامل منطق لازم برای ایجاد پیام‌های خطای سفارشی (و سایر سیاست‌ها) بر اساس شرایط خاصی است که شما تعریف می‌کنید.
  2. یک بخش <DefaultFaultRule> که در شرایط زیر یک پیام خطای پیش‌فرض ایجاد می‌کند:
    • هیچ <FaultRules> تعریف نشده است.
    • هیچ <FaultRules> موجود اجرا نمی‌شود.
    • عنصر <AlwaysEnforce> روی true تنظیم شده است.

در اصل، پروکسی API به شما این امکان را می‌دهد که یک پیام خطای سفارشی را برگردانید و منطق دیگری را فعال کنید. اگر پروکسی هیچ یک از این بخش‌ها را پیدا نکند، یا وجود داشته باشند اما هیچ خطای سفارشی فعال نشده باشد، پروکسی پیام پیش‌فرض تولید شده توسط Edge خود را ارسال می‌کند.

مثال ساده مدیریت خطا

بیایید با یک مثال ساده شروع کنیم، که در آن فراخوانی یک پروکسی API حاوی کلید API مورد نیاز نیست. به طور پیش‌فرض، پاسخی که به برنامه کلاینت بازگردانده می‌شود به صورت زیر است:

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

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

کاربران API شما ممکن است بتوانند پیام خطا را تشخیص دهند، اما ممکن است نتوانند. و بسیاری از خطاهای پیش‌فرض ظریف‌تر و رمزگشایی آنها دشوارتر است.

به عنوان یک توسعه‌دهنده API، این وظیفه شماست که این پیام را تغییر دهید تا نیازهای هر کسی که در نهایت پیام خطا را دریافت می‌کند، برآورده شود، چه یک توسعه‌دهنده برنامه iOS باشد و چه یک گروه آزمایش داخلی که الزامات قالب پیام خطای خاص خود را دارد.

در اینجا یک مثال ساده از نحوه ایجاد یک پیام خطای سفارشی برای مدیریت این خطا آورده شده است. این کار به ۱) یک سیاست (policy) که پیام سفارشی را تعریف کند، و ۲) یک FaultRule که سیاست را هنگام ورود پروکسی به حالت خطا اجرا کند، نیاز دارد.

۱. سیاستی ایجاد کنید که پیام سفارشی را تعریف کند

ابتدا، یک سیاست ایجاد کنید که پیام خطای سفارشی را تعریف کند. می‌توانید از هر نوع سیاستی، مانند سیاست AssignMessage ، که می‌تواند یک payload و هدرهای HTTP اختیاری مانند کد وضعیت و عبارت دلیل را تنظیم کند، استفاده کنید. Assign Message برای این کار ایده‌آل است. این به شما امکان می‌دهد payload پیام را کنترل کنید، یک کد وضعیت HTTP متفاوت تنظیم کنید، یک عبارت دلیل HTTP متفاوت تنظیم کنید و هدرهای HTTP اضافه کنید.

این سیاست را به هیچ جریانی در پروکسی API متصل نکنید. همین که در بسته پروکسی وجود داشته باشد کافی است. برای انجام این کار در ویرایشگر پروکسی رابط کاربری مدیریت، به برگه توسعه (Develop) بروید و در پنل ناوبری (Navigation) روی نماد + در نوار سیاست‌ها (Policies) کلیک کنید.

این به شما امکان می‌دهد بدون اتصال یک سیاست به جریانی در پروکسی API، آن را ایجاد کنید. سیاستی که به هیچ جریانی متصل نیست، با نماد "جدا شده" در لیست سیاست‌ها، همانطور که در کنار سیاست پیام کلید API نشان داده شده در شکل قبلی نشان داده شده است، علامت‌گذاری می‌شود.

در زیر مثالی از سیاست AssignMessage آمده است که:

  • یک پیام JSON را برمی‌گرداند.
  • یک کد وضعیت HTTP تنظیم می‌کند (۹۱۱، که یک کد وضعیت آشکارا ناموجود است، صرفاً برای نشان دادن انعطاف‌پذیری شما). کد وضعیت در هدر HTTP ظاهر می‌شود.
  • یک عبارت دلیل HTTP تنظیم می‌کند (تا جایگزین عبارت دلیل پیش‌فرض "Unauthorized" برای این خطای فقدان کلید API شود). عبارت دلیل در کنار کد وضعیت در هدر HTTP ظاهر می‌شود.
  • یک هدر HTTP جدید به نام 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>

وقتی این سیاست اجرا شود، پاسخ به برنامه کلاینت به شکل زیر خواهد بود. آن را با پاسخ پیش‌فرض نشان داده شده قبلی مقایسه کنید.

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

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

بله، کمی احمقانه است، اما به شما نشان می‌دهد که چه چیزهایی ممکن است. حداقل حالا توسعه‌دهنده‌ای که پیام را دریافت می‌کند می‌داند که فراموش کرده یک کلید API را به عنوان پارامتر پرس‌وجو وارد کند.

اما این سیاست چگونه اجرا می‌شود؟ بخش بعدی به شما نشان می‌دهد.

۲. <FaultRule> را ایجاد کنید که سیاست را فعال می‌کند.

در بخش‌های <ProxyEndpoint> یا <TargetEndpoint> از پیکربندی پروکسی، یک بلوک XML <FaultRules> اضافه خواهید کرد که شامل یک یا چند بخش <FaultRule> مجزا است. هر FaultRule نشان‌دهنده‌ی خطای متفاوتی است که می‌خواهید مدیریت کنید. در این مثال ساده، ما فقط از یک FaultRule استفاده می‌کنیم تا نشان دهیم از چه اجزایی تشکیل شده است.

همچنین باید یک <DefaultFaultRule> اضافه کنید تا در صورت اجرا نشدن هیچ یک از FaultRules، یک پیام خطای عمومی سفارشی ارائه دهد.

مثال

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

نکات کلیدی:

  • FaultRules در ProxyEndpoint تعریف می‌شوند. این مهم است. بعداً در مورد قرار دادن FaultRules در ProxyEndpoint در مقابل TargetEndpoint بیشتر صحبت خواهیم کرد.
  • <Name> - نام سیاستی که باید اجرا شود. این نام از ویژگی name سیاست در عنصر والد گرفته شده است، همانطور که در مثال سیاست قبلی نشان داده شده است.
  • <Condition> - Edge شرط را ارزیابی می‌کند و فقط در صورتی که شرط درست باشد، سیاست را اجرا می‌کند. اگر چندین FaultRule وجود داشته باشد که به true ارزیابی شوند، Edge اولین موردی را که true باشد اجرا می‌کند. ( مهم : ترتیب ارزیابی FaultRuleها، از بالا به پایین یا از پایین به بالا، بین TargetEndpoint و ProxyEndpoint متفاوت است، همانطور که در بخش Multiple FaultRules و منطق اجرا توضیح داده شده است.) اگر شرطی را وارد نکنید، FaultRule به طور خودکار true می‌شود. اما این بهترین روش نیست. هر FaultRule باید شرط خاص خود را داشته باشد.

  • <DefaultFaultRule> - اگر هیچ FaultRule سفارشی اجرا نشود، <DefaultFaultRule> اجرا می‌شود و به جای پیام پیش‌فرض و مرموز تولید شده توسط Edge، یک پیام سفارشی عمومی‌تر ارسال می‌کند. یک <DefaultFaultRule> همچنین می‌تواند یک <Condition> داشته باشد، اما در بیشتر موارد شما آن را وارد نمی‌کنید، زیرا می‌خواهید به عنوان آخرین راه حل، صرف نظر از هر چیز دیگری، اجرا شود.

    DefaultFaultRule معمولاً برای برگرداندن یک پیام خطای عمومی برای هرگونه خطای غیرمنتظره استفاده می‌شود. به عنوان مثال، پیامی که حاوی اطلاعات تماس برای پشتیبانی فنی است. این پاسخ پیش‌فرض دو هدف را دنبال می‌کند: ارائه اطلاعات مناسب برای توسعه‌دهنده و در عین حال مبهم‌سازی URLهای backend یا سایر اطلاعاتی که ممکن است برای به خطر انداختن سیستم استفاده شوند.

چندین FaultRules و منطق اجرا

در بخش مثال ساده‌ی مدیریت خطا ، ما از یک مثال ساده از یک FaultRule و یک شرط استفاده کردیم. در یک پروژه‌ی API در دنیای واقعی، با وجود تمام خطاهای ممکنی که می‌توانند رخ دهند، احتمالاً چندین FaultRule و یک DefaultFaultRule در هر دو <ProxyEndpoint> و <TargetEndpoint> خود خواهید داشت. در نهایت، تنها یک FaultRule زمانی اجرا می‌شود که یک پروکسی API به حالت خطا برود.

این بخش، منطقی را که Edge در مدیریت FaultRules استفاده می‌کند، از نحوه‌ی رسیدن به یک FaultRule واحد برای اجرا گرفته تا نحوه‌ی مدیریت شرایط Step «درونی» هنگام فعال شدن FaultRule آنها، شرح می‌دهد. این بخش همچنین راهنمایی‌هایی در مورد زمان تعریف FaultRules در <ProxyEndpoint> در مقابل <TargetEndpoint> ارائه می‌دهد و رابطه‌ی بین FaultRules و سیاست RaiseFault را شرح می‌دهد.

اجرای FaultRules

به طور خلاصه، منطقی که Edge هنگام مواجهه با خطا در پروکسی API استفاده می‌کند، به این صورت است. توجه داشته باشید که تفاوت اندکی بین ارزیابی FaultRules در ProxyEndpoint و TargetEndpoint وجود دارد.

  1. Edge بسته به محل وقوع خطا، FaultRules را در ProxyEndpoint یا TargetEndpoint ارزیابی می‌کند:
    • ProxyEndpoint - Edge با <FaultRule> پایینی در XML پیکربندی شروع می‌کند و به سمت بالا می‌رود و <Condition> هر <FaultRule> را ارزیابی می‌کند (شرط «بیرونی»، نه شرط‌های <Step> «درونی».)
    • TargetEndpoint - Edge با بالاترین <FaultRule> در XML پیکربندی شروع می‌کند و به سمت پایین حرکت می‌کند و <Condition> هر <FaultRule> را ارزیابی می‌کند (شرط "بیرونی"، نه شرط‌های "درونی" <Step> ).
  2. اولین FaultRule که شرط آن درست باشد را اجرا می‌کند. اگر یک FaultRule هیچ شرطی نداشته باشد، به طور پیش‌فرض درست است.
    • وقتی یک FaultRule اجرا می‌شود، تمام مراحل داخل FaultRule به ترتیب از بالا به پایین در پیکربندی XML ارزیابی می‌شوند. مراحل بدون شرط به طور خودکار اجرا می‌شوند (سیاست‌ها اجرا می‌شوند)، و مراحلی که <Condition> آنها "true" ارزیابی می‌شود، اجرا می‌شوند (شرط‌هایی که "false" ارزیابی می‌شوند، اجرا نمی‌شوند).
    • اگر یک FaultRule اجرا شود، اما هیچ مرحله‌ای در FaultRule اجرا نشود (زیرا شرایط آنها "false" ارزیابی می‌شود)، پیام خطای پیش‌فرض تولید شده توسط Edge به برنامه کلاینت بازگردانده می‌شود. <DefaultFaultRule> اجرا نمی‌شود ، زیرا Edge قبلاً یک FaultRule خود را اجرا کرده است.

  3. اگر هیچ FaultRule اجرا نشود، Edge در صورت وجود، <DefaultFaultRule> را اجرا می‌کند.

در ادامه مثال‌هایی با کامنت‌های درون‌خطی آمده است.

اجرای ProxyEndpoint

ارزیابی ProxyEndpoint FaultRules از پایین به بالا است، بنابراین خواندن را از آخرین FaultRule در نمونه زیر شروع کنید و به ترتیب به سمت بالا پیش بروید. در آخر به DefaultFaultRule نگاه کنید.

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

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

اجرای TargetEndpoint

ارزیابی TargetEndpoint FaultRules از بالا به پایین است، بنابراین خواندن را از اولین FaultRule در نمونه زیر شروع کنید و به سمت پایین بروید. در آخر به DefaultFaultRule نگاه کنید.

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

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

ترتیب قاعده خطا

همانطور که در مثال قبلی مشاهده می‌کنید، ترتیب قرار دادن FaultRules بسته به اینکه خطا در ProxyEndpoint رخ می‌دهد یا TargetEndpoint، مهم است.

برای مثال:

ترتیب پروکسی-اندپوینت ترتیب TargetEndpoint

در مثال زیر، از آنجایی که ارزیابی از پایین به بالا است، FaultRule 3 اجرا می‌شود، به این معنی که FaultRule های 2 و 1 ارزیابی نمی‌شوند.

۵. قانون خطا ۱: نادرست

۴. قانون خطای ۲: درست

۳. قانون خطای ۳: درست

۲. قانون خطای ۴: نادرست

۱. قانون خطا: ۵ غلط

در مثال زیر، از آنجایی که ارزیابی از بالا به پایین است، FaultRule 2 اجرا می‌شود، به این معنی که FaultRule های 3، 4 و 5 ارزیابی نمی‌شوند.

۱. قانون خطای ۱: نادرست

۲. قانون خطای ۲: درست

۳. قانون خطای ۳: درست

۴. قانون خطای ۴: نادرست

۵. قانون خطا: ۵ غلط

سیاست‌هایی که باید لحاظ شوند

شما می‌توانید هر سیاستی را از یک FaultRule با قرار دادن آنها در Steps اجرا کنید. برای مثال، می‌توانید یک سیاست AssignMessage را برای قالب‌بندی پاسخ به برنامه کلاینت اجرا کنید، سپس یک پیام را با سیاست MessageLogging ثبت کنید. سیاست‌ها به ترتیبی که شما آنها را قرار می‌دهید (از بالا به پایین در XML) اجرا می‌شوند.

قوانین خطا فقط در حالت خطا فعال می‌شوند (در مورد continueOnError)

ممکن است به نظر برسد که عنوان مطلب تکراری است، اما یک نکته‌ی ظریف در رابطه با خطای پروکسی که باعث می‌شود پروکسی API وارد حالت خطا شود - یا بهتر بگوییم، وارد حالت خطا نشود - وجود دارد که باید از آن آگاه باشید: ویژگی continueOnError در یک سیاست.

خلاصه: یک پروکسی API <FaultRules> و <DefaultFaultRule> را فقط در صورتی ارزیابی می‌کند که پروکسی وارد حالت خطا شده باشد. این بدان معناست که حتی اگر یک شرط FaultRule به صورت درست ارزیابی شود، اگر پروکسی در حالت خطا نباشد، فعال نمی‌شود.

با این حال، در اینجا مثالی از وقوع خطا و عدم ورود پروکسی به حالت خطا آورده شده است. در هر سیاستی، می‌توانید یک ویژگی به نام continueOnError را روی عنصر والد تنظیم کنید. این ویژگی در رابطه با مدیریت خطا بسیار مهم است، زیرا تعیین می‌کند که آیا پروکسی در صورت عدم موفقیت سیاست وارد حالت خطا می‌شود یا خیر. در بیشتر موارد، بهتر است مقدار پیش‌فرض continueOnError="false" را حفظ کنید، که در صورت عدم موفقیت سیاست، پروکسی را در حالت خطا قرار می‌دهد و مدیریت خطای سفارشی شما فعال می‌شود. با این حال، اگر continueOnError="true" (به عنوان مثال، اگر نمی‌خواهید عدم موفقیت فراخوانی سرویس، اجرای پروکسی را متوقف کند)، پروکسی در صورت عدم موفقیت آن سیاست وارد حالت خطا نمی‌شود و پروکسی به FaultRules شما نگاه نمی‌کند.

برای اطلاعات در مورد ثبت خطاها هنگام continueOnError="true" ، به مدیریت خطاهای خط‌مشی در جریان فعلی مراجعه کنید.

محل تعریف FaultRules: ProxyEndpoint یا TargetEndpoint

وقتی یک پروکسی API با خطایی مواجه می‌شود، این خطا یا در <ProxyEndpoint> (درخواست از یا پاسخ به برنامه کلاینت) یا در <TargetEndpoint> (درخواست از یا پاسخ از سرویس هدف) رخ می‌دهد. هر کجا که این خطا رخ دهد، همان جایی است که Edge به دنبال FaultRules می‌گردد.

برای مثال، اگر سرور هدف در دسترس نباشد (کد وضعیت HTTP 503)، پروکسی API در پاسخ <TargetEndpoint> به حالت خطا می‌رود و جریان عادی پروکسی API به <ProxyEndpoint> ادامه پیدا نمی‌کند. اگر FaultRules فقط در <ProxyEndpoint> تعریف شده باشد، آنها آن خطا را مدیریت نمی‌کنند.

یک مثال دیگر: اگر یک سیاست RaiseFault در پاسخ <ProxyEndpoint> باعث ایجاد خطا شود، یک FaultRule در <TargetEndpoint> اجرا نخواهد شد.

سیاست FaultRules در مقابل سیاست RaiseFault

قوانین خطا و سیاست RaiseFault ممکن است در ظاهر مانند روش‌های جایگزین برای انجام مدیریت خطا به نظر برسند؛ و از برخی جهات این درست است. اما آنها همچنین با هم کار می‌کنند. این بخش رابطه بین این دو را توضیح می‌دهد. درک این رابطه باید به شما در طراحی مدیریت خطای خود کمک کند، به خصوص اگر می‌خواهید از هر دو استفاده کنید.

به طور خلاصه:

  • قوانین خطا همیشه زمانی ارزیابی می‌شوند که یک پروکسی API وارد حالت خطا شود.
  • سیاست RaiseFault روشی برای قرار دادن یک پروکسی API در حالت خطا است، زمانی که در غیر این صورت خطایی رخ نمی‌داد.

    برای مثال، اگر می‌خواهید در صورتی که کد وضعیت HTTP در پاسخ از سرویس هدف بزرگتر از ۲۰۰ باشد، خطایی صادر کنید، باید یک سیاست RaiseFault در جریان پاسخ خود اضافه کنید. چیزی شبیه به این خواهد بود:

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

    خط‌مشی RaiseFault همچنین یک پیام خطا به برنامه‌ی کلاینت ارسال می‌کند.

چه اتفاقی می‌افتد وقتی که یک سیاست RaiseFault باعث ایجاد خطا می‌شود، که پروکسی را در حالت خطا قرار می‌دهد، که به طور بالقوه یک FaultRule را اجرا می‌کند؟ اینجاست که اوضاع می‌تواند کمی پیچیده شود. اگر سیاست RaiseFault یک پیام خطا برگرداند و یک FaultRule فعال شود و یک پیام خطا برگرداند، چه چیزی به برنامه کلاینت برگردانده می‌شود؟

  • از آنجایی که FaultRule یا DefaultFaultRule پس از سیاست RaiseFault اجرا می‌شوند، داده‌های پاسخ FaultRule برنده می‌شوند.
  • داده‌های پاسخ سیاست RaiseFault (کد وضعیت، عبارت دلیل یا بار داده پیام) در صورتی استفاده می‌شوند که آن داده‌ها توسط FaultRule یا DefaultFaultRule تنظیم نشده باشند.
  • اگر هم سیاست RaiseFault و هم FaultRule هدرهای HTTP سفارشی اضافه کنند، هر دو در پاسخ گنجانده می‌شوند. نام‌های هدر تکراری، هدری با چندین مقدار ایجاد می‌کنند.

در اینجا مثالی از آنچه توسط یک سیاست RaiseFault و یک FaultRule تنظیم می‌شود و آنچه به برنامه کلاینت بازگردانده می‌شود، آورده شده است. این نمونه‌ها برای اختصار طراحی شده‌اند، نه برای بهترین شیوه‌ها.

برنامه کلاینت موارد زیر را دریافت می‌کند :

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

<- سیاست قوانین خطا این را تنظیم می‌کند :

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

<- سیاست RaiseFault این را تنظیم می‌کند :

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

شرایط ساختمان

شرط‌ها کلید اجرای FaultRule هستند. شما شرط‌های FaultRule را به همان روشی ایجاد می‌کنید که برای سایر شرط‌ها در Edge، مانند جریان‌های شرطی یا شرط‌های RaiseFault، انجام می‌دهید.

برای اینکه بقیه‌ی این بخش را در چارچوب قرار دهید، در اینجا یک نمونه قانون خطا آورده شده است که دارای یک شرط بیرونی FaultRule و یک شرط درونی Step است.

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

متغیرهای مختص خطاهای سیاستی

متغیرهای fault.name و {policy_namespace}.{policy_name}.failed زمانی در دسترس هستند که یک سیاست خطایی ایجاد کند.

نام.خطا

وقتی یک سیاست با شکست مواجه می‌شود، با استفاده از متغیر fault.name ، خطا را در یک شرط دریافت کنید. برای مثال:

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

نام خطا در پیام خطای پیش‌فرض ظاهر می‌شود. برای مثال، در مثال زیر، نام خطا FailedToResolveAPIKey است. در این حالت، یک متغیر جریان به نام fault.name روی مقدار FailedToResolveAPIKey تنظیم شده است.

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

بنابراین شرط به این شکل خواهد بود:

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

برای فهرستی از خطاهای خط‌مشی، به مرجع خطای خط‌مشی مراجعه کنید.

{policy_namespace}.{policy_name}.failed

متغیر *.failed زمانی در دسترس است که یک سیاست با شکست مواجه شود. در زیر نمونه‌هایی از متغیرهای *.failed برای سیاست‌های مختلف آمده است. برای فضاهای نام سیاست، به متغیرهای جریان در هر موضوع مرجع سیاست مراجعه کنید.

سایر متغیرهای موجود

وقتی یک پروکسی API به حالت خطا می‌رود، تنها متغیرهای موجود برای استفاده در شرط‌ها عبارتند از:

  • متغیرهای سیاستی که شکست خورد.
  • متغیرهای پیام HTTP که در نقطه شکست وجود دارند. برای مثال، اگر خطایی در پاسخ رخ دهد، یک FaultRule در <TargetEndpoint> می‌تواند از داده‌های HTTP response.status.code ، message.content ، error.content و غیره استفاده کند. یا اگر یک سیاست Quota با شکست مواجه شود، می‌توانید از متغیر ratelimit.{quota_policy_name}.exceed.count استفاده کنید. از ابزار Trace و مباحث مرجع سیاست برای کمک به شما در تشخیص متغیرها و داده‌های HTTP موجود استفاده کنید.

اطلاعات بیشتر

  • شرایط : مرجع شرایط و متغیرها و شرایط جریان

  • خطاها : مرجع خطای سیاست
  • متغیرها : متغیرها به متغیرها ارجاع می‌دهند و برای متغیرهایی که با هر سیاست در دسترس هستند، به صفحات مرجع سیاست جداگانه مراجعه کنید.

بهترین شیوه‌ها برای مدیریت خطا

مدیریت خطا یک وظیفه مهم طراحی معماری برای توسعه پروکسی API است. مهم است که برای فهمیدن چگونگی و زمان مدیریت خطاها، تعیین پیام‌های خطا و طراحی قالب‌های پیام خطا وقت بگذارید. پس از (یا همزمان با) فهمیدن این موارد، از این بهترین شیوه‌ها برای کمک به پیاده‌سازی مدیریت خطا استفاده کنید.

در ادامه برخی از بهترین شیوه‌ها در طراحی و ساخت مدیریت خطا ارائه شده است:

  • برای هر FaultRule، یک <Condition> "بیرونی" (همزاد عنصر <Step> ) ارائه دهید. قوانین خطایی که هیچ شرط بیرونی ندارند، به طور خودکار به مقدار درست ارزیابی می‌شوند. شرط‌های مرحله‌ای "درونی" برای تعیین درست یا نادرست بودن یک FaultRule استفاده نمی‌شوند . شرط‌های مرحله‌ای فقط پس از اجرای FaultRule حاوی آنها توسط Edge ارزیابی می‌شوند. در یک FaultRule، معمولاً چندین مرحله با سیاست‌های Assign Message (یا سایر) وجود دارد که هر کدام دارای یک شرط مرحله‌ای هستند.
  • برای مدیریت خطاها در چندین سیاست از یک نوع (مثلاً چندین سیاست سهمیه‌بندی)، برای هر خطای سیاستی که احتمالاً دریافت می‌کنید، یک FaultRule ایجاد کنید. به عنوان مثال، برای هر خطای احتمالی در سیاست‌های سهمیه‌بندی، مانند QuotaViolation ، InvalidMessageWeight ، StartTimeNotSupported ، یک FaultRule ایجاد کنید. (برای خطاهای سیاست‌گذاری به مرجع خطای سیاست‌گذاری مراجعه کنید. همانطور که خطاهای بیشتری را که باید مدیریت شوند کشف می‌کنید، می‌توانید بعداً برگردید و آنها را به FaultRules خود اضافه کنید. تکرارپذیری اشکالی ندارد، اگرچه نیاز به بازاستقرار پروکسی دارد.) این رویکرد به شما امکان می‌دهد بدون توجه به اینکه کدام سیاست آن را ایجاد می‌کند، همان نوع خطا را دریافت کنید، که باعث می‌شود FaultRules XML شما کارآمد باشد.

    سپس اگر به کنترل خطای دقیق‌تری نیاز دارید، از شرط‌های inner Step استفاده کنید. برای مثال، اگر در جریان درخواست خود، هم سهمیه توسعه‌دهنده‌ی انفرادی و هم سهمیه‌ی سراسری را با دو سیاست اعمال می‌کنید، شرط "بیرونی" FaultRule خود را طوری تنظیم کنید که در صورت خطای QuotaViolation فعال شود (که در هر دو حالت، زمانی که سهمیه از حد مجاز تجاوز کند، اجرا می‌شود). سپس شرط‌های Step را طوری تنظیم کنید که متغیرهای exceed.count را در هر دو سیاست سهمیه‌ی شما ارزیابی کنند. فقط خطای مربوطه به کلاینت ارسال می‌شود (اضافه‌ی سهمیه‌ی توسعه‌دهنده یا اضافه‌ی سهمیه‌ی سراسری). در اینجا مثالی از این پیکربندی آمده است:

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

    برای مثال دیگری، به این تاپیک انجمن Apigee مراجعه کنید.

  • برای مدیریت خطاها وقتی از یک سیاست واحد از یک نوع استفاده می‌کنید، یک قانون خطای واحد را در نظر بگیرید که در صورت عدم موفقیت آن سیاست اجرا می‌شود و چندین مرحله را در نظر بگیرید که به هر خطای ممکن نگاشت می‌شوند. این کار با استفاده از یک FaultRule واحد به جای چندین FaultRule (یکی برای هر نوع خطا) باعث می‌شود XML شما کارآمد بماند. به عنوان مثال:

    <FaultRule name="raise-fault-3">
    <!-- This condition catches *any* error in the Verify-API-Key-1 policy. -->
      <Condition>(oauthV2.Verify-API-Key-1.failed = "true")</Condition>
      <!-- This first step always executes, which handles errors you haven't mapped with inner conditions. -->
      <Step>
        <Name>Generic-Key-Fault</Name>
      </Step>
      <Step>
        <Name>Assign-Message-Raise-Fault-1</Name>
        <Condition>(fault.name = "FailedToResolveAPIKey")</Condition>
      </Step>
      <Step>
        <Name>Assign-Message-Raise-Fault-2</Name>
        <Condition>(fault.name = "InvalidApiKey")</Condition>
      </Step>
    </FaultRule>
  • FaultRules را در جایی که خطاها رخ می‌دهند (سمت کلاینت <ProxyEndpoint> یا سمت هدف <TargetEndpoint> ) اضافه کنید. FaultRules را برای هر خط‌مشی که در هر مکان ظاهر می‌شود، اضافه کنید.
  • در FaultRules، می‌توانید هر نوع سیاستی را اجرا کنید که بتواند پیامی را به برنامه‌ی کلاینت برگرداند. سیاست AssignMessage برای این کار ایده‌آل است. همچنین اگر می‌خواهید خطاها را پیگیری کنید، ثبت پیام با سیاست MessageLogging را در نظر بگیرید.
  • هنگام استفاده از سیاست‌های RaiseFault همراه با FaultRules، داده‌های پاسخی که هنگام بازگشت داده‌ها توسط هر دو سیاست RaiseFault و FaultRule ارسال می‌شوند را هماهنگ کنید. به عنوان مثال، اگر سیاست RaiseFault شما کد وضعیت HTTP را بازنشانی می‌کند، FaultRule کد وضعیت را بازنشانی نمی‌کند. بدترین اتفاقی که می‌تواند رخ دهد این است که کد وضعیت پیش‌فرض به برنامه کلاینت بازگردانده شود.
  • اجرای <DefaultFaultRule> :
    • اگر می‌خواهید یک <DefaultFaultRule> همیشه زمانی که هیچ FaultRule دیگری اجرا نمی‌شود، اجرا شود، <Condition> را روی آن قرار ندهید.
    • اگر می‌خواهید یک <DefaultFaultRule> همیشه اجرا شود، حتی زمانی که یک FaultRule دیگر اجرا شده است، عنصر فرزند <AlwaysEnforce>true</AlwaysEnforce> را اضافه کنید.

الگویی برای مدیریت متمرکز و قابل استفاده مجدد خطا

پست زیر از انجمن Apigee الگویی برای مدیریت متمرکز خطا بدون تکرار کد را شرح می‌دهد:

الگوی مدیریت خطا برای پروکسی‌های Apigee

ایجاد FaultRules

برای افزودن یک FaultRule، باید پیکربندی XML مربوط به ProxyEndpoint یا TargetEndpoint را ویرایش کنید. می‌توانید از رابط کاربری Edge برای انجام این ویرایش در پنل Code از نمای Develop برای یک پروکسی API استفاده کنید، یا فایل XML که ProxyEndpoint یا TargetEndpoint را تعریف می‌کند، ویرایش کنید.

اگر FaultRules را در رابط کاربری مدیریت ایجاد می‌کنید، ابتدا سیاست‌هایی را که می‌خواهید اجرا کنید ایجاد کنید، سپس آنها را به پیکربندی FaultRule اضافه کنید. (اگر سعی کنید یک FaultRule را ذخیره کنید که به سیاستی اشاره دارد که هنوز ایجاد نشده است، در رابط کاربری با خطا مواجه خواهید شد.)

افزودن سیاست‌ها به یک FaultRule

در حالی که می‌توانید هر سیاستی را در FaultRule قرار دهید، معمولاً از سیاست AssignMessage برای تولید یک پیام پاسخ سفارشی برای یک وضعیت خطا استفاده می‌کنید. AssignMessage به شما امکان می‌دهد یک پاسخ HTTP را با بار داده، کد وضعیت HTTP، هدرها و عناصر عبارت دلیل پیکربندی کنید.

مثال زیر یک پیکربندی معمول از سیاست AssignMessage را نشان می‌دهد:

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

اکنون می‌توانید از این سیاست در FaultRule خود استفاده کنید. توجه کنید که چگونه در FaultRule به سیاست AssignMessage با نام ارجاع می‌دهید:

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

وقتی پیکربندی بالا را پیاده‌سازی می‌کنید، پروکسی API هر زمان که برنامه‌ای کلید API نامعتبری ارائه دهد، سیاست AssignMessage به نام fault_invalidkey را اجرا می‌کند.

همانطور که در مثال زیر نشان داده شده است، می‌توانید چندین سیاست را در یک FaultRule اجرا کنید:

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

سیاست‌ها به ترتیب تعریف‌شده اجرا می‌شوند. برای مثال، می‌توانید از سیاست MessageLogging ، سیاست ExtractVariables ، سیاست AssignMessage یا هر سیاست دیگری در FaultRule استفاده کنید. توجه داشته باشید که پردازش FaultRule در صورت وقوع هر یک از این شرایط فوراً متوقف می‌شود:

  • هر سیاستی در FaultRule باعث خطا می‌شود.
  • هر یک از سیاست‌های موجود در FaultRule از نوع RaiseFault است.

تعریف پیام خطای سفارشی برگردانده شده از یک FaultRule

به عنوان یک روش برتر، شما باید پاسخ‌های خطای واضحی را از APIهای خود تعریف کنید. به این ترتیب، اطلاعات منسجم و مفیدی را به مشتریان خود ارائه می‌دهید.

مثال سیاست AssignMessage زیر از تگ‌های <Payload> ، <StatusCode> و <ReasonPhase> برای تعریف پاسخ خطای سفارشی ارسال شده به کلاینت در صورت خطای InvalidApiKey استفاده می‌کند (به مثال قبلی 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>

این پاسخ شامل موارد زیر است:

  • محتوای مخرب (payload) حاوی پیام خطا و یک آدرس ایمیل برای تماس با پشتیبانی.
  • کد وضعیت HTTP در پاسخ برگردانده شده است.
  • عبارت دلیل، که توضیح کوتاهی از خطا است.

ایجاد یک DefaultFaultRule

یک DefaultFaultRule برای هر خطایی که به طور صریح توسط FaultRule دیگری مدیریت نمی‌شود، به عنوان یک مدیریت‌کننده خطا عمل می‌کند. اگر شرایط برای همه FaultRuleها با خطا مطابقت نداشته باشد، DefaultFaultRule خطا را مدیریت می‌کند. مدیریت پیش‌فرض خطا را با اضافه کردن برچسب <DefaultFaultRule> به عنوان یک عنصر فرزند از یک ProxyEndpoint یا یک TargetEndpoint فعال کنید.

برای مثال، پیکربندی TargetEndpoint زیر یک DefaultFaultRule تعریف می‌کند که سیاستی به نام 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 معمولاً برای برگرداندن یک پیام خطای عمومی برای هرگونه خطای غیرمنتظره، مانند پیامی که حاوی اطلاعات تماس برای پشتیبانی فنی است، استفاده می‌شود. این پاسخ پیش‌فرض دو هدف را دنبال می‌کند: ارائه اطلاعات مناسب برای توسعه‌دهندگان و در عین حال مبهم‌سازی URLهای backend یا سایر اطلاعاتی که ممکن است برای به خطر انداختن سیستم استفاده شوند.

برای مثال، شما سیاست AssignMessage زیر را برای بازگرداندن یک خطای عمومی تعریف می‌کنید:

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

Include the <AlwaysEnforce> element in the <DefaultFaultRule> tag to execute the DefaultFaultRule for every error, even if another FaultRule has already been executed. The DefaultFaultRule is always the last FaultRule to execute:

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

One use of the DefaultFaultRule is to determine the type of error that occurs when you otherwise cannot determine it. For example, your API proxy is failing for an error that you cannot determine. Use the DefaultFaultRule to invoke the following AssignMessage policy. This policy writes the fault.name value to a header named DefaultFaultHeader in the response:

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

You can then view the header in the Edge trace tool or on the response to see what caused the error.

Adding message logging to the PostClientFlow

The PostClientFlow is the only flow that executes after the proxy enters the error state. Only the MessageLogging policy can be attached to this flow, which is executed after the response is sent back to the client. Although attaching the MessageLogging policy to this flow is technically not error handling, you can use it to log information in the event of an error. Because it is executed regardless of whether the proxy succeeded or failed, you can put Message Logging policies in the PostClientFlow and be guaranteed that they always execute.

Handling policy faults within the current flow

The examples shown so far all use a FaultRule on the ProxyEndpoint or TargetEndpoint to handle any policy errors as part of the error state. That is because the default value of the continueOnError element of a policy is false , meaning that when an error occurs in a policy, control is directed to the error state. Once in the error state, you cannot return control back to the normal pipeline and you typically return some form of error message to the calling app.

However, if you set the continueOnError element to true for a policy, control stays in the current flow and the next policy in the pipeline executes after the policy that caused the error. The advantage to handling the error in the current flow is that you might have a way to recover from the error to complete processing of the request.

Shown below is a VerifyAPIKey policy named verify-api-key with the continueOnError element set to true:

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

If the API key is missing or invalid, then the VerifyAPIKey policy sets the oauthV2.verify-api-key.failed variable to true , but processing continues in the current flow.

You then add VerifyAPIKey policy as a step in the PreFlow of the 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>

Notice how the next step in the PreFlow uses a condition to test for the existence of an error. If an error occurred in the VerifAPIKey policy, then the policy named FaultInFlow policy executes. Otherwise, the FaultInFlow policy is skipped. The FaultInFlow policy can do many things, such as logging the error, attempting to fix the error, or performing some other action.

Triggering an error by using the RaiseFault policy

You can use the RaiseFault policy at any time in a flow to trigger an error. When a RaiseFault policy executes, it terminates the current flow and transfers control to the error state.

One use of the RaiseFault policy is to test for a specific condition that another policy might not detect. In the example above, you added a <Condition> tag to a PreFlow <Step> tag that caused the policy FaultInFlow to execute if the condition is met. If FaultInFlow is a RaiseFault policy, then control transfers to the error state. Or, you might insert a RaiseFault policy in a flow to debug and test your FaultRules.

When a RaiseFault policy triggers an error, you can use the following FaultRule and condition to process it:

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

Note that the condition tests for a fault named RaiseFault . The RaiseFault policy always sets the value of fault.name to RaiseFault .

Custom handling of HTTP error codes from the target server

The examples shown in the previous sections apply to errors created by policies. However you can also create a custom response for transport-level errors, meaning HTTP errors returned from the target server. To control the response from an HTTP error, configure a TargetEndpoint to process HTTP response codes.

By default, Edge treats HTTP response codes in the 1xx-3xx range as 'success', and HTTP response codes in the range 4xx-5xx as 'failure'. That means any response from the backend service with an HTTP response code 4xx-5xx automatically invokes the error state, which then returns an error message directly to the requesting client.

You can create custom handlers for any HTTP response codes. For example, you might not want to treat all HTTP response codes in the range 4xx-5xx as 'failure' but only 5xx, or you might want to return custom error messages for HTTP response codes 400 and 500.

In the next example, you use the success.codes property to configure the TargetEndpoint to treat HTTP response codes 400 and 500 as a success, along with the default HTTP codes. By treating those codes as a success, the TargetEndpoint takes over the processing of the response message, instead of invoking the error state:

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

As you can see in this example, you can use wildcards to set the success.codes property to a range of values..

Setting the success.codes property overwrites the default values. Therefore, if you want to add HTTP code 400 to the list of default success codes, set this property as:

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

But, if you only want HTTP code 400 to be treated as a success code, set the property as:

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

You can now define custom handlers for HTTP response codes 400 and 500 to return a customized response message to the requesting app. The following TargetEndpoint uses the policy named ReturnError to handle HTTP 400 and 500 response codes:

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

This TargetEndpoint configuration causes the policy called ReturnError to handle the response whenever the TargetEndpoint encounters an HTTP response code of 400 or 500.

Fault taxonomy

API Services organizes faults into the following categories and subcategories.

دسته بندی زیرشاخه Fault Name توضیحات
پیام‌رسانی Failures that occur during the message flow (not including policy failures)
Custom faults {fault_name} Any faults explicitly handled by the API proxy using the RaiseFault policy
Response codes InternalServerError, NotFound HTTP error codes 5xx, 4xx
Routing failures NoRoutesMatched Failure in selecting a named TargetEndpoint for a request
Classification failures NotFound Failures caused by a request URI that does not match any BasePath for any ProxyEndpoint configurations (that is, no API proxies match the URL in the client app's request)
حمل و نقل HTTP transport-level errors
اتصال ConnectionRefused, ConnectionReset, ConnectionTimeout Failures occur while establishing network or transport-level connections
Request validations ContentLengthMissing, HostHeaderMissing Faults occur during semantics checks on every request
Response validations Faults occur during semantics checks on every response
IO errors SSLHandshakeError, ReadTimeout, ReadError, WriteTimeout, WriteError, ChunkError Read/write errors at client or target endpoints, timeouts, TLS/SSL errors, and chunked errors
سیستم Undefined runtime errors
حافظه OutOfMemory, GCOverLimit Memory-related failures
موضوع RogueTaskTerminated Failures such as termination of run-away tasks
سیاست Faults for each Policy type are defined in the Policy Reference .

An error is always accompanied by a text description of the reason for the failure. When the system raises a fault, a set of attributes are populated to assist in troubleshooting. A fault includes the following information:

  • دلیل
  • User-defined custom attributes