Control de errores y excepciones en Azure Logic Apps

Se aplica a: Azure Logic Apps (consumo + estándar)

La manera en la que una arquitectura de integración controla correctamente el tiempo de inactividad o los problemas causados por sistemas dependientes puede plantear un desafío. Para ayudarle a crear integraciones sólidas y resistentes que controlen correctamente los problemas y los errores, Azure Logic Apps proporciona una experiencia de primera clase para el control de errores y excepciones.

Directivas de reintentos

Para el control de errores y excepciones más básico, puede usar la directiva de reintentos cuando se admita en un desencadenador o una acción, como la acción HTTP. Si la solicitud original del desencadenador o la acción agota el tiempo de espera o produce un error, lo que da lugar a una respuesta 408, 429 o 5xx, la directiva de reintentos especifica que el desencadenador o la acción reenvíe la solicitud por configuración de directiva.

Límites de la directiva de reintentos

Para más información sobre las directivas de reintentos, la configuración, los límites y otras opciones, consulte Límites de las directivas de reintentos.

Tipos de directiva de reintentos

Las operaciones de conector que admiten directivas de reintento usan la directiva predeterminada a menos que seleccione otra.

Directiva de reintentos Descripción
Valor predeterminado Para la mayoría de las operaciones, la directiva de reintento predeterminada es una directiva de intervalo exponencial que envía hasta 4 reintentos a intervalos que aumentan exponencialmente. Estos intervalos escalan en 7,5 segundos, pero se limitan entre los 5 y los 45 segundos. Las operaciones usan una directiva de reintentos predeterminada diferente, como una directiva de intervalo fijo. Para más información, consulte Directiva de reintentos predeterminada.
None No volver a enviar la solicitud. Para más información, consulte Ninguna: sin directiva de reintentos.
Intervalo exponencial Esta directiva espera un intervalo aleatorio seleccionado de un intervalo que crece exponencialmente antes de enviar la solicitud siguiente. Para más información, revise Directiva de reintentos de intervalo exponencial.
Intervalo fijo Esta directiva espera el intervalo especificado antes de enviar la solicitud siguiente. Para más información, revise Directiva de reintentos de intervalo fijo.

Cambio del tipo de directiva de reintentos en el diseñador

  1. En Azure Portal abra el flujo de trabajo de la aplicación lógica en el diseñador.

  2. En función de si está trabajando en un flujo de trabajo de consumo o estándar, abra la configuración del desencadenador o la acción.

    • Consumo: en la forma de la acción, abra el menú de puntos suspensivos (...) y seleccione Configuración.

    • Estándar: en el diseñador, seleccione la acción. En el panel de detalles, seleccione Configuración.

  3. Si la acción o el desencadenador admiten directivas de reintentos, seleccione el tipo de directiva que desee en Directiva de reintentos.

Cambio del tipo de directiva de reintentos en el editor de vista Código

  1. Si es necesario, confirme si el desencadenador o la acción admiten directivas de reintentos completando los pasos anteriores en el diseñador.

  2. Abra el flujo de trabajo de la aplicación lógica en el editor de vista Código.

  3. En la definición del desencadenador o la acción, agregue el objeto JSON retryPolicy al objeto inputs de ese desencadenador o acción. De lo contrario, si no existe ningún objeto retryPolicy, el desencadenador o la acción usan la directiva de reintentos default.

    "inputs": {
       <...>,
       "retryPolicy": {
          "type": "<retry-policy-type>",
          // The following properties apply to specific retry policies.
          "count": <retry-attempts>,
          "interval": "<retry-interval>",
          "maximumInterval": "<maximum-interval>",
          "minimumInterval": "<minimum-interval>"
       },
       <...>
    },
    "runAfter": {}
    

    Obligatorio

    Propiedad Valor Tipo Descripción
    type <retry-policy-type> String Tipo de directiva de reintentos que se va a usar: default, none, fixed o exponential
    count <retry-attempts> Entero Para los tipos de directiva fixed y exponential, el número de reintentos, que es un valor comprendido entre 1 y 90. Para más información, consulte Intervalo fijo e Intervalo exponencial.
    interval <retry-interval> String Para los tipos de directiva fixed y exponential, el valor del intervalo de reintento en formato ISO 8601. Para la directiva exponential, también puede especificar intervalos máximos y mínimos opcionales. Para más información, consulte Intervalo fijo e Intervalo exponencial.

    Consumo: de 5 segundos (PT5S) a 1 día (P1D).
    Estándar: para flujos de trabajo con estado, de 5 segundos (PT5S) a 1 día (P1D). En el caso de los flujos de trabajo sin estado, de 1 segundo (PT1S) a 1 minuto (PT1M).

    Opcional

    Propiedad Valor Tipo Descripción
    maximumInterval <maximum-interval> String Para la directiva exponential, el intervalo más grande para el intervalo seleccionado aleatoriamente en formato ISO 8601. El valor predeterminado es 1 día (P1D). Para más información, consulte Intervalo exponencial.
    minimumInterval <minimum-interval> String Para la directiva exponential, el intervalo más pequeño para el intervalo seleccionado aleatoriamente en formato ISO 8601. El valor predeterminado es 5 segundos (PT5S). Para más información, consulte Intervalo exponencial.

Directiva de reintentos predeterminada

Las operaciones de conector que admiten directivas de reintento usan la directiva predeterminada a menos que seleccione otra. Para la mayoría de las operaciones, la directiva de reintento predeterminada es una directiva de intervalo exponencial que envía hasta 4 reintentos a intervalos que aumentan exponencialmente. Estos intervalos escalan en 7,5 segundos, pero se limitan entre los 5 y los 45 segundos. Las operaciones usan una directiva de reintentos predeterminada diferente, como una directiva de intervalo fijo.

En la definición del flujo de trabajo, la definición de desencadenador o acción no incluye explícitamente la definición de la directiva predeterminada, pero en el ejemplo siguiente se muestra cómo se comporta la directiva de reintentos predeterminada para la acción HTTP:

"HTTP": {
   "type": "Http",
   "inputs": {
      "method": "GET",
      "uri": "http://myAPIendpoint/api/action",
      "retryPolicy" : {
         "type": "exponential",
         "interval": "PT7S",
         "count": 4,
         "minimumInterval": "PT5S",
         "maximumInterval": "PT1H"
      }
   },
   "runAfter": {}
}

Ninguna: sin directiva de reintentos

Para especificar que la acción o el desencadenador no vuelvan a intentar solicitudes con error, establezca el elemento <retry-policy-type> en none.

Directiva de reintentos de intervalo fijo

Para especificar que la acción o el desencadenador esperen el intervalo especificado antes de enviar la solicitud siguiente, establezca el elemento <retry-policy-type> en fixed.

Ejemplo

Esta directiva de reintentos intenta obtener las últimas noticias dos veces más tras la primera solicitud con error con un retraso de 30 segundos entre cada intento:

"Get_latest_news": {
   "type": "Http",
   "inputs": {
      "method": "GET",
      "uri": "https://mynews.example.com/latest",
      "retryPolicy": {
         "type": "fixed",
         "interval": "PT30S",
         "count": 2
      }
   }
}

Directiva de reintentos de intervalo exponencial

La directiva de reintentos de intervalo exponencial especifica que el desencadenador o la acción espera un intervalo aleatorio antes de enviar la siguiente solicitud. Este intervalo aleatorio se selecciona de un intervalo exponencialmente creciente. Opcionalmente, puede invalidar los intervalos máximos y mínimos predeterminados especificando sus propios intervalos mínimos y máximos, en función de si tiene un flujo de trabajo de la aplicación lógica Estándar o de Consumo.

Nombre Límite para Consumo Límite para Estándar Notas
Retraso máximo Valor predeterminado: 1 día Valor predeterminado: 1 hora Para cambiar el límite predeterminado en un flujo de trabajo de aplicación lógica de Consumo, use el parámetro de directiva de reintentos.

Para cambiar el límite predeterminado en un flujo de trabajo de aplicación lógica Estándar, consulte Edición de la configuración de host y aplicación para aplicaciones lógicas en Azure Logic Apps de inquilino único.

Retraso mínimo Valor predeterminado: 5 segundos Valor predeterminado: 5 segundos Para cambiar el límite predeterminado en un flujo de trabajo de aplicación lógica de Consumo, use el parámetro de directiva de reintentos.

Para cambiar el límite predeterminado en un flujo de trabajo de aplicación lógica Estándar, consulte Edición de la configuración de host y aplicación para aplicaciones lógicas en Azure Logic Apps de inquilino único.

Intervalos variables aleatorios

Para la directiva de reintentos de intervalo exponencial, la tabla siguiente muestra el algoritmo general que usa Azure Logic Apps para generar una variable aleatoria uniforme en el intervalo especificado para cada reintento. El intervalo especificado puede llegar hasta el número de reintentos, incluido.

Número de reintentos Intervalo mínimo Intervalo máximo
1 max(0, <minimum-interval>) min(interval, <maximum-interval>)
2 max(interval, <minimum-interval>) min(2 * interval, <maximum-interval>)
3 max(2 * interval, <minimum-interval>) min(4 * interval, <maximum-interval>)
4 max(4 * interval, <minimum-interval>) min(8 * interval, <maximum-interval>)
.... .... ....

Administración del comportamiento de "ejecución posterior"

Cuando se agregan acciones en el diseñador de flujos de trabajo, se declara de forma implícita el orden que se va a usar para ejecutar dichas acciones. Una vez finalizada la ejecución de una acción, esta se marca con el estado Correcto, Con errores, Omitida o Agotado tiempo de espera. De manera predeterminada, una acción que se agrega en el diseñador solo se ejecuta después de que se complete la predecesora con el estado Correcto. En la definición subyacente de una acción, la propiedad runAfter especifica la acción predecesora que debe finalizar primero y los estados permitidos para esa predecesora antes de que se pueda ejecutar la acción sucesora.

Cuando una acción genera una excepción o un error no controlado, la acción se marca como Con errores y las acciones sucesoras se marcan como Omitidas. Si se produce este comportamiento para una acción que tiene ramas paralelas, el motor de Azure Logic Apps sigue las otras ramas para determinar sus estados de finalización. Por ejemplo, si una rama finaliza con una acción Omitida, el estado de finalización de esa rama se basa en el estado de la predecesora de la acción omitida. Una vez completada la ejecución del flujo de trabajo, el motor determina el estado de la ejecución completa mediante la evaluación de todos los estados de las ramas. Si alguna de las ramas finaliza con un error, la ejecución de todo el flujo de trabajo se marca como Con errores.

Conceptual diagram with examples that show how run statuses are evaluated.

Para asegurarse de que una acción se pueda seguir ejecutando a pesar del estado de su predecesora, puede cambiar el comportamiento de "ejecución posterior" de una acción para controlar los estados incorrectos de la predecesora. De este modo, la acción se ejecuta cuando el estado de la predecesora es Correcto, Con errores, Omitida, Agotado tiempo de espera o todos estos estados.

Por ejemplo, para ejecutar la acción Enviar un correo electrónico de Outlook de Office 365 después de que la acción de Excel Online predecesora Agregar una fila a una tabla se marque como Con errores, en lugar de como Correcto, cambie el comportamiento de "ejecución posterior" mediante el diseñador o el editor de vista Código.

Nota

En el diseñador, la configuración de "ejecución posterior" no se aplica a la acción que sigue inmediatamente al desencadenador, ya que el desencadenador se debe ejecutar correctamente antes de que se pueda ejecutar la primera acción.

Cambio del comportamiento de "ejecución posterior" en el diseñador

  1. En Azure Portal abra el flujo de trabajo de la aplicación lógica en el diseñador.

  2. En el diseñador, seleccione la forma de la acción. En el panel de detalles, seleccione Ejecutar después de.

    Screenshot showing Standard workflow designer and current action details pane with

    El panel Ejecutar después de muestra la acción predecesora de la acción seleccionada actualmente.

    Screenshot showing Standard designer, current action, and

  3. Expanda el nodo de la acción predecesora para ver todos los estados de "ejecución posterior".

    De manera predeterminada, el estado de "ejecución posterior" se establece en es correcto. Por lo tanto, la acción predecesora se debe ejecutar correctamente antes de que se pueda ejecutar la acción seleccionada actualmente.

    Screenshot showing Standard designer, current action, and default

  4. Cambie el comportamiento de "ejecución posterior" al estado que prefiera. Asegúrese de seleccionar primero una opción antes de borrar la opción predeterminada. Siempre debe tener al menos una opción seleccionada.

    En el ejemplo siguiente, se ha seleccionado con errores.

    Screenshot showing Standard designer, current action, and

  5. Para especificar que la acción se ejecute si la acción predecesora se marca como Con errores, Omitida o Agotado tiempo de espera, seleccione los otros estados.

    Screenshot showing Standard designer, current action, and multiple

  6. Para requerir que se ejecute más de una acción predecesora, cada una con sus propios estados de "ejecución posterior", expanda la lista Seleccionar acciones. Seleccione las acciones predecesoras que desee y especifique los estados de "ejecución posterior" necesarios.

    Screenshot showing Standard designer, current action, and multiple predecessor actions available.

  7. Cuando lo tenga todo preparado, seleccione Listo.

Cambio del comportamiento de "ejecución posterior" en el editor de vista Código

  1. En Azure Portal, abra el flujo de trabajo de la aplicación lógica en el editor de vista Código.

  2. En la definición JSON de la acción, edite la propiedad runAfter, que tiene la siguiente sintaxis:

    "<action-name>": {
       "inputs": {
          "<action-specific-inputs>"
       },
       "runAfter": {
          "<preceding-action>": [
             "Succeeded"
          ]
       },
       "type": "<action-type>"
    }
    
  3. En este ejemplo, cambie la propiedad runAfter de Succeeded a Failed:

    "Send_an_email_(V2)": {
       "inputs": {
          "body": {
             "Body": "<p>Failed to add row to table: @{body('Add_a_row_into_a_table')?['Terms']}</p>",
             "Subject": "Add row to table failed: @{body('Add_a_row_into_a_table')?['Terms']}",
             "To": "Sophia.Owen@fabrikam.com"
          },
          "host": {
             "connection": {
                "name": "@parameters('$connections')['office365']['connectionId']"
             }
          },
          "method": "post",
          "path": "/v2/Mail"
       },
       "runAfter": {
          "Add_a_row_into_a_table": [
             "Failed"
          ]
       },
       "type": "ApiConnection"
    }
    
  4. Para especificar que la acción se ejecute si la acción predecesora se marca como Failed, Skipped o TimedOut, agregue los otros estados:

    "runAfter": {
       "Add_a_row_into_a_table": [
          "Failed", "Skipped", "TimedOut"
       ]
    },
    

Evaluación de las acciones con ámbitos y sus resultados

De forma similar a la ejecución de pasos después de acciones individuales con la configuración de "ejecución posterior", puede agrupar acciones dentro de un ámbito. Puede usar ámbitos si desea agrupar acciones lógicamente, evaluar el estado global del ámbito y realizar acciones basadas en ese estado. Una vez que todas las acciones de un ámbito acaben de ejecutarse, el propio ámbito obtiene su estado.

Para comprobar el estado de un ámbito, puede usar los mismos criterios que usa para comprobar el estado de ejecución de un flujo de trabajo, como Correcto, Con errores, etc.

De forma predeterminada, cuando las acciones del ámbito se ejecutan correctamente, el estado del ámbito se marca como Succeeded. Si la acción final de un ámbito se marca como Con errores o Anulado, el estado del ámbito se marca como Con errores.

Para capturar las excepciones en un ámbito Con errores y ejecutar acciones que controlen estos errores, puede usar la configuración de "ejecución posterior" de ese ámbito Con errores. De ese modo, si cualquier acción del ámbito produce un error, y usa la configuración de "ejecución posterior" para ese ámbito, puede crear una única acción para capturar los errores.

Para conocer los límites en los ámbitos, consulte Límites y configuración.

Obtención del contexto y resultados de errores

Aunque la captura de errores desde un ámbito es útil, quizás también quiera más contexto como ayuda para comprender exactamente qué acciones han producido un error y los errores o códigos de estado. La función result() devuelve los resultados de las acciones de nivel superior de una acción con ámbito. Esta función acepta el nombre del ámbito como un único parámetro y devuelve una matriz con los resultados de esas acciones de nivel superior. Estos objetos de acción tienen los mismos atributos que los devueltos por la función actions(), como la hora de inicio, la hora de finalización, el estado, las entradas, los identificadores de correlación y las salidas de la acción.

Nota

La función result() devuelve los resultados solo de las acciones de nivel superior y no de las acciones anidadas más profundas, como las acciones Switch o Condition.

Para obtener contexto sobre las acciones que produjeron errores en un ámbito, puede usar la expresión @result() con el nombre del ámbito y la configuración de "ejecución posterior". Para filtrar la matriz devuelta por las acciones cuyo estado es Con errores, puede agregar la acción Filtrar matriz. Para ejecutar una acción para una acción errónea devuelta, tome la matriz filtrada devuelta y use un bucle For each.

El siguiente ejemplo de código JSON envía una solicitud HTTP POST con el cuerpo de la respuesta de todas las acciones que produjeron un error dentro de la acción de ámbito My_scope. Una explicación detallada sigue al ejemplo.

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

En los pasos siguientes, se describe lo que sucede en este ejemplo:

  1. Para obtener el resultado de todas las acciones de My_Scope, la acción Filtrar matriz usa esta expresión de filtro: @result('My_Scope')

  2. La condición para Filtrar matriz es cualquier elemento @result() que tenga un estado Failed. Esta condición filtra la matriz que contiene todos los resultados de acción de My_Scope a una matriz con solo los resultados de acción que hayan producido un error.

  3. Realiza una acción de bucle For_each en las salidas de la matriz filtrada. Este paso realiza una acción para cada resultado de acción con errores que se filtrara antes.

    Si solo se produce un error en una acción del ámbito, las acciones del bucle For_each solo se ejecutan una vez. Muchas acciones con error causan una acción por cada error.

  4. Envía una solicitud HTTP POST en el cuerpo de respuesta del elemento For_each, que es la expresión @item()['outputs']['body'].

    La forma del elemento @result() es la misma que la forma de @actions() y se puede analizar del mismo modo.

  5. Incluya dos encabezados personalizados con el nombre de la acción con errores (@item()['name']) y el id. de seguimiento de cliente de la ejecución con errores @item()['clientTrackingId'].

Como referencia, este es un ejemplo de un solo elemento @result(), que muestra las propiedades name, body y clientTrackingId que se analizan en el ejemplo anterior. Fuera de una acción For_each, @result() devuelve una matriz de estos objetos.

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

Para poner en práctica diferentes patrones de control de excepciones, puede usar las expresiones descritas anteriormente en este artículo. Podría optar por ejecutar una única acción de control de excepciones fuera del ámbito, que acepte toda la matriz filtrada de errores y quite la acción For_each. También puede incluir otras propiedades útiles de la respuesta \@result(), como se ha mostrado antes.

Configuración de los registros de Azure Monitor

Los patrones anteriores son formas útiles de controlar los errores y las excepciones que se producen dentro de una ejecución. Sin embargo, también puede identificar y responder a los errores que se producen independientemente de la ejecución. Para evaluar los estados de ejecución, puede supervisar los registros y las métricas de las ejecuciones, o publicarlos en la herramienta de supervisión que prefiera.

Por ejemplo, Azure Monitor proporciona una manera simplificada de enviar todos los eventos del flujo de trabajo, incluidos todos los estados de ejecución y acción, a un destino. Puede configurar alertas para métricas y umbrales específicos en Azure Monitor. También puede enviar eventos de flujo de trabajo a un área de trabajo de Log Analytics o a una cuenta de almacenamiento de Azure. O bien, puede transmitir todos los eventos mediante Azure Event Hubs a Azure Stream Analytics. En Stream Analytics, puede escribir consultas en directo de anomalías, promedios o errores de los registros de diagnóstico. Asimismo, puede usar Stream Analytics para enviar información a otros orígenes de datos, como colas, temas, SQL, Azure Cosmos DB o Power BI.

Para más información, consulte Configuración de registros de Azure Monitor y recopilación de datos de diagnóstico para Azure Logic Apps.

Pasos siguientes