Gestire errori ed eccezioni in App per la logica di AzureHandle errors and exceptions in Azure Logic Apps

App per la logica di Azure offre un set completo di strumenti e modelli per garantire la solidità e la resilienza delle integrazioni dell'utente in caso di errori.Azure Logic Apps provides rich tools and patterns to help you make sure your integrations are robust and resilient against failures. In qualsiasi architettura di integrazione, una delle sfide è garantire che i tempi di inattività o i problemi dei sistemi dipendenti vengano gestiti in modo appropriato.Any integration architecture poses the challenge of making sure to appropriately handle downtime or issues from dependent systems. App per la logica ottimizza la gestione degli errori offrendo gli strumenti necessari per intervenire in caso di eccezioni ed errori nei flussi di lavoro.Logic Apps makes handling errors a first-class experience, giving you the tools you need to act on exceptions and errors in your workflows.

Criteri di ripetizione dei tentativiRetry policies

Il tipo più semplice di gestione degli errori e delle eccezioni è costituito dai criteri di ripetizione.A retry policy is the most basic type of exception and error handling. Tali criteri definiscono se e come l'azione dovrà essere ripetuta in caso di timeout o esito negativo, con restituzione di una risposta 429 o 5xx, della richiesta iniziale.If an initial request timed out or failed (any request that results in a 429 or 5xx response), this policy defines if and how the action should retry. Esistono tre tipi di criteri di ripetizione de tentativi exponential, fixed e none.There are three types of retry policies, exponential, fixed, and none. Se i criteri di ripetizione dei tentativi non vengono indicati nella definizione del flusso di lavoro, viene usato il criterio predefinito.If a retry policy is not provided in the workflow definition, then the default policy is used. È possibile configurare i criteri di ripetizione dei tentativi nell'input di una determinata azione o trigger se ripetibile.You can configure retry policies in the inputs for a particular action or trigger if it is retryable. Analogamente, in Progettazione app per la logica è possibile configurare (se applicabile) i criteri di ripetizione dei tentativi nelle impostazioni per un dato blocco.Similarly, in the Logic App Designer retry policies can be configured (if applicable) under the setttings for a given block.

Per informazioni sulle limitazioni dei criteri di ripetizione dei tentativi, vedere Limiti e configurazione per App per la logica e per altre informazioni sulla sintassi supportata, vedere la sezione relativa ai criteri di ripetizione di tentativi in Trigger e azioni dei flussi di lavoro.For information on the limitations of retry policies, see Logic Apps limits and configuration and for more information on supported syntax, see the retry-policy section in Workflow Actions and Triggers.

Intervallo esponenzialeExponential interval

Il tipo di criterio exponential riproverà una richiesta non riuscita dopo un intervallo di tempo casuale da un intervallo in crescita esponenziale.The exponential policy type will retry a failed request after a random time interval from an exponentially growing range. Per ogni tentativo si garantisce l'invio di un intervallo casuale maggiore di minimumInterval e minore di maximumInterval.Each retry attempt is guaranteed to be sent at a random interval that is greater than minimumInterval and less than maximumInterval. Una variabile casuale uniforme nell'intervallo casuale verrà generato per ogni nuovo tentativo fino a e includendo il conteggio:A uniform random variable in the below range will be generated for each retry up to and including count:

Intervallo variabile casualeRandom Variable Range

Numero di tentativiRetry Number Intervallo minimoMinimum Interval Intervallo massimoMaximum Interval
11 Massimo (0, minimumInterval)Max(0, minimumInterval) Minimo (intervallo, maximumInterval)Min(interval, maximumInterval)
22 Massimo (intervallo, minimumInterval)Max(interval, minimumInterval) Minimo (2 * intervallo, maximumInterval)Min(2 * interval, maximumInterval)
33 Massimo (2intervallo, **minimumInterval)Max(2interval, minimumInterval) Minimo (4 * intervallo, maximumInterval)Min(4 * interval, maximumInterval)
44 Massimo (4intervallo, **minimumInterval)Max(4 * interval, **minimumInterval*) Minimo (8 * intervallo, maximumInterval)Min(8 * interval, maximumInterval)
......

Per i criteri di tipo exponential, sono necessari conteggio e intervallo, mentre minimumIntervall e maximumInterval possono essere facoltativamente inseriti per sostituire i valori predefiniti di PT5S e PT1D rispettivamente.For exponential type policies, count and interval are required while minimumInterval and maximumInterval can be optionally provided to override the default values of PT5S and PT1D respectively.

Nome dell'elementoElement name ObbligatoriaRequired TipoType DescrizioneDescription
typetype Yes StringString exponential
countcount Yes IntegerInteger numero di tentativi di ripetizione, devono essere compresi tra 1 e 90number of retry attempts, must be between 1 and 90
intervalinterval Yes StringString intervallo ripetizione dei tentativi nel formato ISO 8601, deve essere compreso tra PT5S e PT1Dretry interval in ISO 8601 format, must be between PT5S and PT1D
minimumIntervalminimumInterval NoNo StringString intervallo di ripetizione dei tentativi minimo nel formato ISO 8601, deve essere compreso tra PT5S e l'intervalloretry minimum interval in ISO 8601 format, must be between PT5S and interval
maximumIntervalmaximumInterval NoNo StringString intervallo di ripetizione dei tentativi minimo nel formato ISO 8601, deve essere compreso tra l'intervallo e PT1Dretry minimum interval in ISO 8601 format, must be between interval and PT1D

Intervallo fissoFixed interval

Il tipo di criterio fixed ripeterà una richiesta non riuscita attendendo l'intervallo di tempo specificato prima di inviare la richiesta successiva.The fixed policy type will retry a failed request by waiting the provided interval of time before sending the next request.

Nome dell'elementoElement name ObbligatoriaRequired TipoType DescrizioneDescription
typetype Yes StringString fixed
countcount Yes IntegerInteger numero di tentativi di ripetizione, devono essere compresi tra 1 e 90number of retry attempts, must be between 1 and 90
intervalinterval Yes StringString intervallo ripetizione dei tentativi nel formato ISO 8601, deve essere compreso tra PT5S e PT1Dretry interval in ISO 8601 format, must be between PT5S and PT1D

NessunoNone

Il tipo di criteri none non ritenterà una richiesta non riuscita.The none policy type will not retry a failed request.

Nome dell'elementoElement name ObbligatoriaRequired TipoType DescrizioneDescription
typetype Yes StringString none

DefaultDefault

Se non è definito alcun criterio per i tentativi, vengono usati i criteri predefiniti.If no retry policy is specified, then the default policy is used. Il criterio predefinito è un criterio di intervallo esponenziale che consente di inviare fino a 4 ripetizioni di tentativi, a intervalli con crescita esponenziale ridimensionati di 7,5 secondi e compresi tra 5 e 45 secondi.The default policy is an exponential interval policy which will send up to 4 retries, at exponentially increasing intervals scaled by 7.5 seconds and capped to between 5 and 45 seconds. Il criterio predefinito (usato quando retryPolicy non è stato definito) è equivalente al criterio in questa definizione del flusso di lavoro HTTP di esempio:This default policy (used when retryPolicy is undefined) is equivalent to the policy in this example HTTP workflow definition:

"HTTP":
{
    "inputs": {
        "method": "GET",
        "uri": "http://myAPIendpoint/api/action",
        "retryPolicy" : {
            "type": "exponential",
            "count": 4,
            "interval": "PT7.5S",
            "minimumInterval": "PT5S",
            "maximumInterval": "PT45S"
        }
    },
    "runAfter": {},
    "type": "Http"
}

Rilevare gli errori con la proprietà runAfterCatch failures with the RunAfter property

Ogni azione di un'app per la logica dichiara le azioni che devono essere completate prima del proprio avvio. Si ottiene così una sorta di ordinamento dei passaggi del flusso di lavoro.Each logic app action declares which actions must finish before the action starts, like ordering the steps in your workflow. Tale ordinamento è costituito dalla proprietà runAfter nella definizione dell'azione,In the action definition, this ordering is known as the runAfter property. un oggetto che descrive le azioni e gli stati delle azioni che determineranno l'esecuzione dell'azione.This property is an object that describes which actions and action statuses execute the action. Per impostazione predefinita, tutte le azioni aggiunte tramite la finestra di progettazione di app per la logica vengono impostate per essere eseguite dopo il passaggio precedente (runAfter) se il passaggio precedente risulta Succeeded.By default, all actions added through the Logic App Designer are set to runAfter the previous step if the previous step Succeeded. È possibile personalizzare questo valore per attivare le azioni quando lo stato delle azioni precedenti è Failed, Skipped o un possibile insieme di questi valori.However, you can customize this value to fire actions when previous actions have Failed, Skipped, or a possible set of these values. Se si vuole aggiungere un elemento a un argomento del bus di servizio designato dopo l'esito negativo di una specifica azione Insert_Row, usare la configurazione runAfter seguente:If you wanted to add an item to a designated Service Bus topic after a specific action Insert_Row fails, you could use the following runAfter configuration:

"Send_message": {
    "inputs": {
        "body": {
            "ContentData": "@{encodeBase64(body('Insert_Row'))}",
            "ContentType": "{ \"content-type\" : \"application/json\" }"
        },
        "host": {
            "api": {
                "runtimeUrl": "https://logic-apis-westus.azure-apim.net/apim/servicebus"
            },
            "connection": {
                "name": "@parameters('$connections')['servicebus']['connectionId']"
            }
        },
        "method": "post",
        "path": "/@{encodeURIComponent('failures')}/messages"
    },
    "runAfter": {
        "Insert_Row": [
            "Failed"
        ]
    }
}

Si noti che la proprietà runAfter è impostata per essere attivata se l'azione Insert_Row è Failed.Notice the runAfter property is set to fire if the Insert_Row action is Failed. Per eseguire l'azione se lo stato dell'azione è Succeeded, Failed o Skipped, usare la sintassi seguente:To run the action if the action status is Succeeded, Failed, or Skipped, use this syntax:

"runAfter": {
        "Insert_Row": [
            "Failed", "Succeeded", "Skipped"
        ]
    }

Suggerimento

Le azioni eseguite dopo l'esito negativo di un'azione precedente e completate correttamente vengono contrassegnate come Succeeded.Actions that run and complete successfully after a preceding action has failed, are marked as Succeeded. Con questo comportamento, se tutti gli errori in un flusso di lavoro vengono rilevati l'esecuzione stessa verrà contrassegnata come Succeeded.This behavior means that if you successfully catch all failures in a workflow, the run itself is marked as Succeeded.

Ambiti e risultati per la valutazione delle azioniScopes and results to evaluate actions

Così come è possibile configurare l'esecuzione dopo singole azioni, è anche possibile raggruppare insieme le azioni all'interno di un ambito, che fungerà da raggruppamento logico delle azioni.Similar to how you can run after individual actions, you can also group actions together inside a scope, which act as a logical grouping of actions. Gli ambiti sono utili sia per organizzare le azioni delle app per la logica sia per eseguire valutazioni aggregate sullo stato di un ambito.Scopes are useful both for organizing your logic app actions, and for performing aggregate evaluations on the status of a scope. L'ambito in sé riceve uno stato dopo che sono state completate tutte le azioni al suo interno.The scope itself receives a status after all actions in a scope have finished. Lo stato dell'ambito è determinato con gli stessi criteri usati per un'esecuzione:The scope status is determined with the same criteria as a run. se l'azione finale in un ramo di esecuzione è Failed o Aborted, lo stato è Failed.If the final action in an execution branch is Failed or Aborted, the status is Failed.

È possibile usare runAfter dopo che è un ambito è stato contrassegnato come Failed per attivare azioni specifiche per gli eventuali errori verificatisi all'interno dell'ambito.To fire specific actions for any failures that happened within the scope, you can use runAfter with a scope that is marked Failed. L'esecuzione dopo l'esito negativo di un ambito consente di creare una singola azione per rilevare gli errori in caso di esito negativo di qualsiasi azione all'interno dell'ambito.If any actions in the scope fail, running after a scope fails lets you create a single action to catch failures.

Recupero del contesto degli errori con i risultatiGetting the context of failures with results

Rilevare gli errori è molto utile, ma può essere opportuno anche il contesto per comprendere esattamente quali azioni hanno avuto esito negativo e tutti gli errori o i codici di stato restituiti.Although catching failures from a scope is useful, you might also want context to help you understand exactly which actions failed, and any errors or status codes that were returned. La funzione @result() del flusso di lavoro offre il contesto relativo al risultato di tutte le azioni all'interno di un ambito.The @result() workflow function provides context about the result of all actions in a scope.

@result() accetta un unico parametro, il nome dell'ambito, e restituisce una matrice dei risultati di tutte le azioni di tale ambito.@result() takes a single parameter, scope name, and returns an array of all the action results from within that scope. Tali oggetti azione includono gli stessi attributi dell'oggetto @actions() , come ora di inizio, ora di fine, stato, input, ID di correlazione e output dell'azione.These action objects include the same attributes as the @actions() object, including action start time, action end time, action status, action inputs, action correlation IDs, and action outputs. Per inviare il contesto di qualsiasi azione non riuscita all'interno di un ambito, è possibile associare una funzione @result() a runAfter.To send context of any actions that failed within a scope, you can easily pair an @result() function with a runAfter.

Se si vuole eseguire un'azione per ogni azione di un ambito con stato Failed, è possibile associare @result() a un'azione Filtra matrice e a un ciclo ForEach. Ciò consente di filtrare la matrice dei risultati in modo da ottenere le azioni non riuscite.To execute an action for each action in a scope that Failed, filter the array of results to actions that failed, you can pair @result() with a Filter Array action and a ForEach loop. La matrice dei risultati filtrata può quindi essere usata per eseguire un'azione per ogni errore con il ciclo ForEach .You can take the filtered result array and perform an action for each failure using the ForEach loop. L'esempio seguente, seguito da una spiegazione dettagliata, invia una richiesta HTTP POST con il corpo della risposta di qualsiasi azione non riuscita all'interno dell'ambito My_Scope.Here's an example, followed by a detailed explanation, that sends an HTTP POST request with the response body of any actions that failed within the scope My_Scope.

"Filter_array": {
    "inputs": {
        "from": "@result('My_Scope')",
        "where": "@equals(item()['status'], 'Failed')"
    },
    "runAfter": {
        "My_Scope": [
            "Failed"
        ]
    },
    "type": "Query"
},
"For_each": {
    "actions": {
        "Log_Exception": {
            "inputs": {
                "body": "@item()['outputs']['body']",
                "method": "POST",
                "headers": {
                    "x-failed-action-name": "@item()['name']",
                    "x-failed-tracking-id": "@item()['clientTrackingId']"
                },
                "uri": "http://requestb.in/"
            },
            "runAfter": {},
            "type": "Http"
        }
    },
    "foreach": "@body('Filter_array')",
    "runAfter": {
        "Filter_array": [
            "Succeeded"
        ]
    },
    "type": "Foreach"
}

Ecco la procedura dettagliata eseguita:Here's a detailed walkthrough to describe what happens:

  1. Per ottenere il risultato di tutte le azioni all'interno di My_Scope, l'azione Filtra matrice filtra @result('My_Scope').To get the result of all actions within My_Scope, the Filter Array action filters @result('My_Scope').

  2. La condizione per Filtra matrice è qualsiasi elemento @result() con stato uguale a Failed.The condition for Filter Array is any @result() item that has status equal to Failed. Questa condizione filtra la matrice con tutti i risultati dell'azione da My_Scope a una matrice con i soli risultati delle azioni non riuscite.This condition filters the array with all action results from My_Scope to an array with only failed action results.

  3. Esecuzione di un'azione For Each sugli output Matrice filtrata.Perform a For Each action on the Filtered Array outputs. Questo passaggio esegue un'azione per ogni risultato di azione non riuscita precedentemente filtrato.This step performs an action for each failed action result that was previously filtered.

    Se una sola azione nell'ambito ha avuto esito negativo, le azioni in foreach vengono eseguite una sola volta.If a single action in the scope failed, the actions in the foreach run only once. Molte azioni non riuscite determinano un'azione per errore.Many failed actions cause one action per failure.

  4. Invio di HTTP POST nel corpo della risposta dell'elemento foreach, ovvero @item()['outputs']['body'].Send an HTTP POST on the foreach item response body, or @item()['outputs']['body']. La forma dell'elemento @result() è uguale alla forma di @actions() e può essere analizzata nello stesso modo.The @result() item shape is the same as the @actions() shape, and can be parsed the same way.

  5. Inclusione di due intestazioni personalizzate con il nome dell'azione non riuscita @item()['name'] e l'ID rilevamento client dell'esecuzione non riuscita @item()['clientTrackingId'].Include two custom headers with the failed action name @item()['name'] and the failed run client tracking ID @item()['clientTrackingId'].

Come riferimento, di seguito è riportato un esempio di un singolo elemento @result(), che mostra le proprietà name, body, e clientTrackingId analizzate nell'esempio precedente.For reference, here's an example of a single @result() item, showing the name, body, and clientTrackingId properties that are parsed in the previous example. All'esterno di foreach, @result() restituisce una matrice di questi oggetti.Outside of a foreach, @result() returns an array of these objects.

{
    "name": "Example_Action_That_Failed",
    "inputs": {
        "uri": "https://myfailedaction.azurewebsites.net",
        "method": "POST"
    },
    "outputs": {
        "statusCode": 404,
        "headers": {
            "Date": "Thu, 11 Aug 2016 03:18:18 GMT",
            "Server": "Microsoft-IIS/8.0",
            "X-Powered-By": "ASP.NET",
            "Content-Length": "68",
            "Content-Type": "application/json"
        },
        "body": {
            "code": "ResourceNotFound",
            "message": "/docs/folder-name/resource-name does not exist"
        }
    },
    "startTime": "2016-08-11T03:18:19.7755341Z",
    "endTime": "2016-08-11T03:18:20.2598835Z",
    "trackingId": "bdd82e28-ba2c-4160-a700-e3a8f1a38e22",
    "clientTrackingId": "08587307213861835591296330354",
    "code": "NotFound",
    "status": "Failed"
}

Le espressioni riportate sopra possono essere usate per eseguire diversi modelli di gestione delle eccezioni.To perform different exception handling patterns, you can use the expressions shown previously. È possibile scegliere di eseguire una singola azione di gestione delle eccezioni all'esterno dell'ambito che accetta l'intera matrice filtrata degli errori e rimuovere foreach.You might choose to execute a single exception handling action outside the scope that accepts the entire filtered array of failures, and remove the foreach. È anche possibile includere altre proprietà utili della risposta @result() illustrata sopra.You can also include other useful properties from the @result() response shown previously.

Diagnostica e telemetria di AzureAzure Diagnostics and telemetry

I modelli precedenti sono un ottimo modo per gestire gli errori e le eccezioni in un'esecuzione, ma è possibile anche identificare e rispondere agli errori indipendentemente dall'esecuzione.The previous patterns are great way to handle errors and exceptions within a run, but you can also identify and respond to errors independent of the run itself. Diagnostica di Azure consente di inviare in modo semplice tutti gli eventi del flusso di lavoro (inclusi tutti gli stati delle esecuzioni e delle azioni) a un account di archiviazione di Azure o un hub eventi di Azure.Azure Diagnostics provides a simple way to send all workflow events (including all run and action statuses) to an Azure Storage account or an Azure Event Hub. Per valutare gli stati delle esecuzioni è possibile monitorare i log e le metriche o pubblicarli nello strumento di monitoraggio preferito.To evaluate run statuses, you can monitor the logs and metrics, or publish them into any monitoring tool you prefer. Una possibile opzione consiste nel trasmettere tutti gli eventi tramite un hub eventi di Azure ad Analisi di flusso.One potential option is to stream all the events through Azure Event Hub into Stream Analytics. In Analisi di flusso è possibile scrivere query dinamiche per qualsiasi anomalia, media o errore dei log di diagnostica.In Stream Analytics, you can write live queries off any anomalies, averages, or failures from the diagnostic logs. Analisi di flusso può facilmente inviare output ad altre origini dati come query, argomenti, SQL, Cosmos DB e Power BI.Stream Analytics can easily output to other data sources like queues, topics, SQL, Azure Cosmos DB, and Power BI.

Passaggi successiviNext Steps