مشاركة عبر


التعامل مع أخطاء في التوزيع الموسيقي

تقوم بتنفيذ تنسيقات Durable Functions في الكود، لذا تستخدم ميزات معالجة الأخطاء المدمجة في لغتك. التعامل مع الأخطاء والتعويض لا يتطلب مفاهيم جديدة، لكن بعض سلوكيات التنسيق تستحق المعرفة.

ملحوظة

الإصدار الرابع من نموذج البرمجة Node.js ل Azure Functions متوفر بشكل عام. تم تصميم نموذج v4 لتوفير تجربة أكثر مرونة وسهولة لمطوري JavaScript وTypeScript. لمزيد من المعلومات حول الفروقات بين v3 و v4، راجع دليل الهجرة.

في مقتطفات الكود التالية، تشير جافاسكريبت (PM4) إلى نموذج البرمجة v4، وهو التجربة الجديدة.

التطبيقات التي تستخدم خدمات السحابة تحتاج إلى التعامل مع الإخفاقات، وإعادة المحاولات على جانب العميل جزء مهم من التصميم. تتضمن مجموعات تطوير المهام الدائمة دعم معالجة الأخطاء، وإعادة التكرار، وانتهاء المهلات لمساعدتك على بناء سير عمل قوي.

أخطاء في وظائف النشاط والتنسيقات الفرعية

في Durable Functions، يتم إعادة الاستثناءات غير المعالجة التي تلقى داخل دوال النشاط أو التنسيقات الفرعية إلى وظيفة المنسق باستخدام أنواع استثناءات موحدة.

تقوم وظيفة المنسق التالية بتحويل الأموال بين حسابين:

نموذج العامل المعزول

في Durable Functions C# تظهر الاستثناءات المعزولة وغير المطبقة تحت TaskFailedException.

عادة ما تحدد رسالة الاستثناء وظائف النشاط أو التنسيقات الفرعية التي تسببت في الفشل. للوصول إلى معلومات خطأ أكثر تفصيلا، افحص الخاصية FailureDetails .

[FunctionName("TransferFunds")]
public static async Task Run(
    [OrchestrationTrigger] TaskOrchestrationContext context, TransferOperation transferDetails)
{
    await context.CallActivityAsync("DebitAccount",
        new
        {
            Account = transferDetails.SourceAccount,
            Amount = transferDetails.Amount
        });

    try
    {
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.DestinationAccount,
                Amount = transferDetails.Amount
            });
    }
    catch (TaskFailedException)
    {
        // Refund the source account.
        // Another try/catch could be used here based on the needs of the application.
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.SourceAccount,
                Amount = transferDetails.Amount
            });
    }
}

ملحوظة

  • عادة ما تحدد رسالة الاستثناء وظائف النشاط أو التنسيقات الفرعية التي تسببت في الفشل. للوصول إلى معلومات أكثر تفصيلا عن الخطأ، افحص الموقع FailureDetails .
  • بشكل افتراضي، FailureDetails يتضمن نوع الخطأورسالة الخطأوتتبع المكدس وأي استثناءات داخلية متداخلة (يتم تمثيل كل منها ككائن متكرر FailureDetails ). لإضافة خصائص استثناء إضافية في مخرجات الفشل، راجع تضمين خصائص الاستثناء المخصصة ل FailureDetails (.NET Isolated).

مهم

ملاحظة ترحيل (قيد المعالجة إلى معزولة): في النموذج الجاري، FunctionFailedException.InnerException يحتوي على كائن الاستثناء الأصلي الذي يلقى من النشاط، والذي يمكنك إلقائه وفحصه مباشرة. في نموذج العامل المعزول، TaskFailedExceptionلا يحتوي على الاستثناء الأصلي ك .InnerException بدلا من ذلك، تتوفر تفاصيل الخطأ فقط من خلال الخاصية FailureDetails ، التي توفر خصائص قائمة على السلاسل النصية (ErrorType, ErrorMessage, StackTrace). لا يمكنك إرسال أو الوصول إلى كائن الاستثناء الأصلي مباشرة. استخدم FailureDetails.IsCausedBy<T>() للتحقق من نوع الاستثناء الأصلي.


النموذج أثناء العملية

في Durable Functions C# قيد العملية، يتم طرح الاستثناءات غير المطبقة ك FunctionFailedException.

عادة ما تتضمن رسالة الاستثناء دالة النشاط أو التنسيق الفرعي الذي فشل. للتفاصيل، قم بفحص InnerException.

[FunctionName("TransferFunds")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var transferDetails = context.GetInput<TransferOperation>();

    await context.CallActivityAsync("DebitAccount",
        new
        {
            Account = transferDetails.SourceAccount,
            Amount = transferDetails.Amount
        });

    try
    {
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.DestinationAccount,
                Amount = transferDetails.Amount
            });
    }
    catch (FunctionFailedException)
    {
        // Refund the source account.
        // Another try/catch could be used here based on the needs of the application.
        await context.CallActivityAsync("CreditAccount",
            new
            {
                Account = transferDetails.SourceAccount,
                Amount = transferDetails.Amount
            });
    }
}

ملحوظة

الأمثلة السابقة على C# تستخدم Durable Functions 2.x. بالنسبة ل Durable Functions 1.x، استخدم DurableOrchestrationContext بدلا من IDurableOrchestrationContext. للفروقات في الإصدارات، راجع مقالة Durable Functions versions.

إذا فشل استدعاء دالة CreditAccount الأول، فإن دالة المنسق تعوض عن طريق إعادة رصيد الأموال إلى الحساب المصدر.

في مجموعات تطوير المهام الدائمة، يتم إعادة الاستثناءات غير المدارة التي تلقى ضمن الأنشطة أو التنسيقات الفرعية إلى المنسق الذي يستخدم هذا TaskFailedException النوع. توفر خاصية الاستثناء FailureDetails معلومات مفصلة عن الفشل.

using Microsoft.DurableTask;

[DurableTask(nameof(TransferFundsOrchestration))]
public class TransferFundsOrchestration : TaskOrchestrator<TransferOperation, string>
{
    public override async Task<string> RunAsync(
        TaskOrchestrationContext context, TransferOperation transfer)
    {
        await context.CallActivityAsync(
            nameof(DebitAccountActivity),
            new AccountOperation { Account = transfer.SourceAccount, Amount = transfer.Amount });

        try
        {
            await context.CallActivityAsync(
                nameof(CreditAccountActivity),
                new AccountOperation { Account = transfer.DestinationAccount, Amount = transfer.Amount });
        }
        catch (TaskFailedException ex)
        {
            // Log the failure details
            var details = ex.FailureDetails;

            // Compensate by refunding the source account
            await context.CallActivityAsync(
                nameof(CreditAccountActivity),
                new AccountOperation { Account = transfer.SourceAccount, Amount = transfer.Amount });

            return $"Transfer failed: {details.ErrorMessage}. Compensation completed.";
        }

        return "Transfer completed successfully";
    }
}

إذا فشل نشاط حساب الائتمان ، يكتشف المنسق الاستثناء ويعوض ذلك بإعادة الأموال إلى الحساب المصدر.

أخطاء في استدعاءات نشاط متعددة (خروج مروحة/خروج مروحة)

عندما تستخدم Task.WhenAll لتشغيل عدة استدعاءات نشاط بالتوازي (نمط خروج المروحة/المروحة الداخلية) وتفشل نشاط أو أكثر، await فإنه يظهر الاستثناء الأول فقط. للوصول إلى جميع الأعطال، افحص الخاصية Exception على المرجع Task المعاد بواسطة Task.WhenAll.

نموذج العامل المعزول
var tasks = new[]
{
    context.CallActivityAsync("Activity1", input1),
    context.CallActivityAsync("Activity2", input2),
    context.CallActivityAsync("Activity3", input3),
};

var allTask = Task.WhenAll(tasks);
try
{
    await allTask;
}
catch (TaskFailedException)
{
    // 'await' rethrows only the first exception. To inspect all failures,
    // check allTask.Exception, which is an AggregateException.
    if (allTask.Exception != null)
    {
        foreach (var inner in allTask.Exception.InnerExceptions)
        {
            if (inner is TaskFailedException taskFailed)
            {
                // Use taskFailed.FailureDetails to inspect error details
                var errorType = taskFailed.FailureDetails.ErrorType;
                var errorMessage = taskFailed.FailureDetails.ErrorMessage;
            }
        }
    }
}

النموذج أثناء العملية
var tasks = new[]
{
    context.CallActivityAsync("Activity1", input1),
    context.CallActivityAsync("Activity2", input2),
    context.CallActivityAsync("Activity3", input3),
};

var allTask = Task.WhenAll(tasks);
try
{
    await allTask;
}
catch (FunctionFailedException)
{
    // 'await' rethrows only the first exception. To inspect all failures,
    // check allTask.Exception, which is an AggregateException.
    if (allTask.Exception != null)
    {
        foreach (var inner in allTask.Exception.InnerExceptions)
        {
            if (inner is FunctionFailedException funcFailed)
            {
                // Use funcFailed.InnerException to access the original exception
            }
        }
    }
}

أخطاء في وظائف الكيان

يعتمد التعامل مع الاستثناءات في دوال الكيان على نموذج استضافة Durable Functions:

نموذج العامل المعزول

في Durable Functions معزولة في C# ، يلف وقت التشغيل استثناءات دالة الكيان في EntityOperationFailedException. للحصول على تفاصيل الاستثناء الأصلية، قم بفحص العقار FailureDetails .

[Function(nameof(MyOrchestrator))]
public static async Task<List<string>> MyOrchestrator(
   [Microsoft.Azure.Functions.Worker.OrchestrationTrigger] TaskOrchestrationContext context)
{
    var entityId = new Microsoft.DurableTask.Entities.EntityInstanceId(nameof(Counter), "myCounter");
    try
    {
        await context.Entities.CallEntityAsync(entityId, "Add", 1);
    }
    catch (EntityOperationFailedException ex)
    {
        // Add your error handling
    }

    return new List<string>();
}

النموذج أثناء العملية

في Durable Functions مع C# قيد العملية، تعيد وظائف الكيان أنواع الاستثناءات الأصلية إلى المنسق.

[FunctionName("Function1")]
public static async Task<string> RunOrchestrator(
    [OrchestrationTrigger] IDurableOrchestrationContext context)
{
    try
    {
        var entityId = new EntityId(nameof(Counter), "myCounter");
        await context.CallEntityAsync(entityId, "Add", 1);
    }
    catch (Exception ex)
    {
        // The exception type is InvalidOperationException with the message "this is an entity exception".
    }
    return string.Empty;
}

[FunctionName("Counter")]
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
{
    switch (ctx.OperationName.ToLowerInvariant())
    {
        case "add":
            throw new InvalidOperationException("this is an entity exception");
        case "get":
            ctx.Return(ctx.GetState<int>());
            break;
    }
}

إعادة المحاولة التلقائية عند الفشل

عند استدعاء دوال النشاط أو دوال التنسيق الفرعي، حدد سياسة إعادة محاولة تلقائية. المثال التالي يستدعي دالة حتى ثلاث مرات وينتظر خمس ثوان بين محاولات:

نموذج العامل المعزول
[FunctionName("TimerOrchestratorWithRetry")]
public static async Task Run([OrchestrationTrigger] TaskOrchestrationContext context)
{
    var options = TaskOptions.FromRetryPolicy(new RetryPolicy(
        maxNumberOfAttempts: 3,
        firstRetryInterval: TimeSpan.FromSeconds(5)));

    await context.CallActivityAsync("FlakyFunction", options: options);

    // ...
}

النموذج أثناء العملية
[FunctionName("TimerOrchestratorWithRetry")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    var retryOptions = new RetryOptions(
        firstRetryInterval: TimeSpan.FromSeconds(5),
        maxNumberOfAttempts: 3);

    await context.CallActivityWithRetryAsync("FlakyFunction", retryOptions, null);

    // ...
}

ملحوظة

الأمثلة السابقة على C# هي ل Durable Functions 2.x. بالنسبة ل Durable Functions 1.x، يجب استخدام DurableOrchestrationContext بدلا من IDurableOrchestrationContext. لمزيد من المعلومات حول الفروقات بين الإصدارات، راجع مقال Durable Functions versions.

استدعاء دالة النشاط في المثال السابق يستخدم معاملة لتكوين سياسة إعادة محاولة تلقائية. خصص الوثيقة بهذه الخيارات:

  • الحد الأقصى للمحاولات: الحد الأقصى لعدد المحاولات. إذا تم ضبطه على 1، لا تحدث أي محاولات جديدة.
  • الفاصل الزمني الأول لإعادة المحاولة: مقدار الوقت المطلوب الانتظار قبل محاولة إعادة المحاولة الأولى.
  • معامل التراجع: المعامل المستخدم لتحديد معدل زيادة التراجع. الإعدادات الافتراضية إلى 1.
  • أقصى فترة إعادة محاولة: أقصى مدة زمنية للانتظار بين محاولات إعادة المحاولة.
  • إعادة المحاولة: أقصى وقت يمكن قضاؤه في إعادة المحاولة. افتراضيا، تستمر المحاولات المتكررة إلى أجل غير مسمى.

تتضمن مجموعات تطوير المهام الدائمة طرق جدولة بديلة تعيد محاولة الأنشطة الفاشلة بناء على سياسة مقدمة. هذه الطرق مفيدة للأنشطة التي تقرأ البيانات من خدمات الويب أو تقوم بكتابة idempotent إلى قاعدة البيانات.

using Microsoft.DurableTask;

[DurableTask(nameof(OrchestratorWithRetry))]
public class OrchestratorWithRetry : TaskOrchestrator<string, string>
{
    public override async Task<string> RunAsync(
        TaskOrchestrationContext context, string input)
    {
        // Configure retry policy
        var retryPolicy = new RetryPolicy(
            maxNumberOfAttempts: 3,
            firstRetryInterval: TimeSpan.FromSeconds(5),
            backoffCoefficient: 2.0,
            maxRetryInterval: TimeSpan.FromMinutes(1),
            retryTimeout: TimeSpan.FromMinutes(5));

        var options = TaskOptions.FromRetryPolicy(retryPolicy);

        // Call activity with automatic retry
        string result = await context.CallActivityAsync<string>(
            nameof(UnreliableActivity), input, options);

        return result;
    }
}

خيارات سياسة إعادة المحاولة هي:

  • الحد الأقصى لعدد المحاولات: الحد الأقصى لمحاولات إعادة المحاولة. إذا تم ضبطه على 1، لا تحدث أي محاولات جديدة.
  • الفاصل الزمني الأول لإعادة المحاولة: مقدار الوقت المطلوب الانتظار قبل محاولة إعادة المحاولة الأولى.
  • معامل التراجع: المعامل المستخدم لتحديد معدل زيادة التراجع. الإعدادات الافتراضية إلى 1.
  • أقصى فترة إعادة محاولة: أقصى مدة زمنية للانتظار بين محاولات إعادة المحاولة.
  • مهلة إعادة المحاولة:الحد الأقصى لمقدار الوقت الذي تقضيه في إجراء عمليات إعادة المحاولة.

معالجات إعادة المحاولة المخصصة

في .NET و Java، ينفذ معالجات إعادة المحاولة في الكود عندما لا تكون سياسات إعادة المحاولة التصريحية معبرة بما فيه الكفاية. في لغات أخرى، نفذ منطق إعادة المحاولة باستخدام الحلقات، والتعامل مع الاستثناءات، والمؤقتات لتأخير المحاولات بين المحاولات.

نموذج العامل المعزول
TaskOptions retryOptions = TaskOptions.FromRetryHandler(retryContext =>
{
    // Don't retry anything that derives from ApplicationException
    if (retryContext.LastFailure.IsCausedBy<ApplicationException>())
    {
        return false;
    }

    // Quit after N attempts
    return retryContext.LastAttemptNumber < 3;
});

try
{
    await ctx.CallActivityAsync("FlakeyActivity", options: retryOptions);
}
catch (TaskFailedException)
{
    // Case when the retry handler returns false...
}

النموذج أثناء العملية
RetryOptions retryOptions = new RetryOptions(
    firstRetryInterval: TimeSpan.FromSeconds(5),
    maxNumberOfAttempts: int.MaxValue)
{
    Handle = exception =>
    {
        // Return true to handle and retry, or false to throw.
        if (exception is TaskFailedException failure)
        {
            // Exceptions from task activities are always this type. Inspect the
            // inner exception for more details.
        }

        return false;
    }
};

await ctx.CallActivityWithRetryAsync("FlakeyActivity", retryOptions, null);

معالجات إعادة المحاولة المخصصة

في .NET و Java، نفذ معالجات إعادة المحاولة في الكود للتحكم في منطق إعادة المحاولة. هذا النهج مفيد عندما لا تكون سياسات إعادة المحاولة التصريحية معبرة بما فيه الكفاية.

using Microsoft.DurableTask;

[DurableTask(nameof(OrchestratorWithCustomRetry))]
public class OrchestratorWithCustomRetry : TaskOrchestrator<string, string>
{
    public override async Task<string> RunAsync(
        TaskOrchestrationContext context, string input)
    {
        // Custom retry handler with conditional logic
        TaskOptions retryOptions = TaskOptions.FromRetryHandler(retryContext =>
        {
            // Don't retry if it's a validation error
            if (retryContext.LastFailure.IsCausedBy<ArgumentException>())
            {
                return false;
            }

            // Retry up to 5 times for transient errors
            return retryContext.LastAttemptNumber < 5;
        });

        try
        {
            return await context.CallActivityAsync<string>(
                nameof(UnreliableActivity), input, retryOptions);
        }
        catch (TaskFailedException)
        {
            // All retries exhausted
            return "Operation failed after all retries";
        }
    }
}

مهلات الدوال

إذا استغرقت استدعاء الوظيفة وقتا طويلا، قم بإيقاف الوقت في وظيفة المنسق. أنشئ مؤقتا متينا باستخدام any محدد مهام، كما في المثال التالي:

نموذج العامل المعزول
[Function("TimerOrchestrator")]
public static async Task<bool> Run([OrchestrationTrigger] TaskOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("FlakyFunction");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

النموذج أثناء العملية
[FunctionName("TimerOrchestrator")]
public static async Task<bool> Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    TimeSpan timeout = TimeSpan.FromSeconds(30);
    DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

    using (var cts = new CancellationTokenSource())
    {
        Task activityTask = context.CallActivityAsync("FlakyFunction");
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // success case
            cts.Cancel();
            return true;
        }
        else
        {
            // timeout case
            return false;
        }
    }
}

ملحوظة

الأمثلة السابقة على C# هي ل Durable Functions 2.x. بالنسبة ل Durable Functions 1.x، يجب استخدام DurableOrchestrationContext بدلا من IDurableOrchestrationContext. لمزيد من المعلومات حول الفروقات بين الإصدارات، راجع مقال Durable Functions versions.

ملحوظة

هذه الآلية لا تنهي تنفيذ دالة النشاط التي هي جارية بالفعل. يسمح لوظيفة التنسيق بتجاهل النتيجة والمضي قدما. لمزيد من المعلومات، راجع المؤقتات.

مهلات النشاط

إذا استغرقت مكالمة النشاط وقتا طويلا، يمكنك التوقف عن انتظارها. أنشئ مؤقتا متيما وتنافس عليه مع مهمة النشاط.

using Microsoft.DurableTask;
using System;
using System.Threading;
using System.Threading.Tasks;

[DurableTask(nameof(OrchestratorWithTimeout))]
public class OrchestratorWithTimeout : TaskOrchestrator<string, bool>
{
    public override async Task<bool> RunAsync(
        TaskOrchestrationContext context, string input)
    {
        TimeSpan timeout = TimeSpan.FromSeconds(30);
        DateTime deadline = context.CurrentUtcDateTime.Add(timeout);

        using var cts = new CancellationTokenSource();
        Task activityTask = context.CallActivityAsync(nameof(SlowActivity), input);
        Task timeoutTask = context.CreateTimer(deadline, cts.Token);

        Task winner = await Task.WhenAny(activityTask, timeoutTask);
        if (winner == activityTask)
        {
            // Activity completed in time - cancel the timer
            cts.Cancel();
            return true;
        }
        else
        {
            // Timeout occurred
            return false;
        }
    }
}

ملحوظة

هذه الآلية لا تنهي تنفيذ النشاط الذي هو بالفعل جار. يسمح للموزع بتجاهل النتيجة والمضي قدما. لمزيد من المعلومات، راجع وثائق Timers.

استثناء غير معالج

إذا فشلت وظيفة المنسق مع استثناء غير معالج، يسجل وقت التشغيل تفاصيل الاستثناء، ويكتمل المثيل بحالة معينة Failed .

تضمين خصائص الاستثناءات المخصصة ل FailureDetails (.NET معزولة)

في سير عمل المهام المتينة التي تستخدم نموذج .NET المعزول، يتم تسلسل فشل المهام إلى كائن FailureDetails. افتراضيا، يتضمن الكائن هذه الحقول:

  • ErrorType—اسم نوع الاستثناء
  • Message—رسالة الاستثناء
  • StackTrace—تتبع المكدس المتسلسل
  • InnerFailure—كائن متداخل FailureDetails للاستثناءات الداخلية

بدءا من مايكروسوفت. Azure. Functions.Worker.Extensions.DurableTask v1.9.0، يمكنك توسيع هذا السلوك بتنفيذ IExceptionPropertiesProvider (المعرفة في حزمة Microsoft.DurableTask.Worker بدءا من v1.16.1). يحدد هذا المزود أنواع الاستثناءات والخصائص التي يجب تضمينها في FailureDetails.Properties القاموس.

ملحوظة

  • هذه الميزة متوفرة بصيغة .NET معزولة فقط. دعم Java غير متوفر بعد.
  • تأكد من أنك تستخدم Microsoft. Azure. Functions.Worker.Extensions.DurableTask v1.9.0 أو أحدث.
  • تأكد من أنك تستخدم Microsoft.DurableTask.Worker v1.16.1 أو أحدث.

تنفيذ مزود خصائص الاستثناء

نفذ تخصيصا IExceptionPropertiesProvider لاستخراج وإرجاع الخصائص المختارة للاستثناءات التي تهمك. يتم تسلسل القاموس المرتجع إلى Properties حقل عندما FailureDetails يتم رمي نوع استثناء مطابق.

using Microsoft.DurableTask.Worker;

public class CustomExceptionPropertiesProvider : IExceptionPropertiesProvider
{
    public IDictionary<string, object?>? GetExceptionProperties(Exception exception)
    {
        return exception switch
        {
            ArgumentOutOfRangeException e => new Dictionary<string, object?>
            {
                ["ParamName"] = e.ParamName,
                ["ActualValue"] = e.ActualValue
            },
            InvalidOperationException e => new Dictionary<string, object?>
            {
                ["CustomHint"] = "Invalid operation occurred",
                ["TimestampUtc"] = DateTime.UtcNow
            },
            _ => null // Other exception types not handled
        };
    }
}

تسجيل الموفر

في Program.cs، سجل IExceptionPropertiesProvider المخصص في مضيف العامل المعزول .NET الخاص بك:

using Microsoft.DurableTask.Worker;
using Microsoft.Extensions.DependencyInjection;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults(builder =>
    {
        // Register custom exception properties provider
        builder.Services.AddSingleton<IExceptionPropertiesProvider, CustomExceptionPropertiesProvider>();
    })
    .Build();

host.Run();

بعد تسجيل المزود، أي استثناء يطابق نوعا مناورا يتضمن تلقائيا الخصائص المكونة في .FailureDetails

فشل العينةتفاصيل المخرجات

عندما يحدث استثناء يطابق تكوين مزود الخدمة الخاص بك، يتلقى التنسيق كائنا متسلسلا FailureDetails مثل هذا:

{
  "errorType": "TaskFailedException",
  "message": "Activity failed with an exception.",
  "stackTrace": "...",
  "innerFailure": {
    "errorType": "ArgumentOutOfRangeException",
    "message": "Specified argument was out of range.",
    "properties": {
      "ParamName": "count",
      "ActualValue": 42
    }
  }
}

استثناء غير معالج

إذا فشل الأوركستراتور بسبب استثناء لم يتم التعامل معه، يقوم وقت التشغيل بتسجيل تفاصيل الاستثناء، وتكتمل الحالة بالحالة Failed . يحتوي على TaskFailedException خاصية FailureDetails تتضمن نوع الخطأ، الرسالة، وتتبع المكدس.

الخطوات التالية