Manejo de errores y diseño de reintentos en Power Automate ── cómo evitar que «el flujo que funcionaba se detenga sin que nadie se entere»

· Actualizado el: · · Power Automate, Manejo de errores, Flujos en la nube, Reintentos, Idempotencia, Monitoreo operativo, Automatización de procesos, Consultoría técnica

«El flujo de recuento que funcionaba todas las mañanas llevaba en realidad detenido desde la semana pasada», «el flujo de registro de pedidos procesó dos veces los mismos datos y se generaron duplicados en el registro». Este tipo de consultas son habituales entre empresas que crean flujos con Power Automate y empiezan a operarlos. El patrón se repite: crear el flujo fue sencillo, pero nadie se dio cuenta de que se había detenido.

Un flujo de Power Automate, si solo se considera el camino normal, puede funcionar en cuestión de horas. Pero el servicio de destino se cae de forma temporal, la autenticación caduca, y siempre acaban llegando datos inesperados. Un flujo que no ha sido diseñado para responder a «qué ocurre cuando falla» va acumulando fallos en silencio y, en el peor de los casos, se desactiva automáticamente a los 14 días1. En este artículo se organizan, desde la clasificación de los fallos de un flujo hasta las especificaciones exactas del reintento estándar, el patrón Try-Catch-Finally con ámbitos, el mecanismo para detectar los fallos y la reejecución y la idempotencia, los patrones de diseño de manejo de errores necesarios para soportar una operación en producción. Cuándo usar cada parte de Power Automate y el manejo de errores del lado de la automatización de interfaz (flujos de escritorio) se tratan en «Automatizar procesos con Power Automate ── cuándo usar flujos en la nube o de escritorio, y diseño del manejo de errores», así que este artículo se centra específicamente en los flujos en la nube.

1. Antes que nada, la conclusión

  • Conviene pensar los fallos en cuatro categorías: «fallo temporal», «causado por los datos», «permisos o autenticación caducados» y «cambio de especificación». El reintento estándar solo resuelve la primera; las otras tres requieren un mecanismo de detección y corrección2.
  • La directiva de reintento estándar solo actúa cuando la solicitud agota el tiempo de espera o falla con una respuesta 408, 429 o 5xx. De forma predeterminada usa un retroceso exponencial, y el número de reintentos es de hasta 2 o 12 veces según el nivel de licencia (perfil de rendimiento)31.
  • La forma básica del manejo de errores es un patrón Try-Catch-Finally construido con ámbitos (scopes) y la «Configuración de ejecución posterior». En esa configuración se elige entre cuatro estados: «si se ha realizado correctamente», «si ha fallado», «si se ha omitido» y «si se ha agotado el tiempo de espera»34. Cabe señalar que esta función se llama «実行条件の構成» en la interfaz japonesa y «run after» en la interfaz y la documentación en inglés; en este artículo se usa de forma uniforme el nombre que aparece en la interfaz, «Configuración de ejecución posterior».
  • Una vez que Catch procesa el fallo, al final hay que registrar la ejecución como «con error» mediante la acción Terminate. Si se olvida este paso, la ejecución aparecerá como exitosa en el historial y el fallo quedará silenciado43.
  • El correo de notificación de fallos predeterminado está limitado a los «fallos con una solución conocida» y tiene un período de enfriamiento de 28 días: es un mecanismo con demasiados huecos como para confiar solo en él. Conviene considerar obligatoria una notificación propia desde el bloque Catch5.
  • El historial de ejecuciones solo es visible durante 28 días de forma predeterminada. Un flujo que sigue fallando se desactiva automáticamente a los 14 días. Por diseño, es perfectamente posible «darse cuenta un mes después de que el flujo estaba detenido»61.
  • Para estar preparados ante la reejecución (reenvío) y el inicio duplicado, conviene incorporar desde el principio un diseño idempotente que sea seguro aunque se ejecute dos veces (marca de «ya procesado», upsert en lugar de creación, condiciones de disparador)78.

2. Cómo falla un flujo ── las cuatro categorías de fallo

Diseñar el manejo de errores resulta más ordenado si se empieza clasificando «cómo puede fallar» el flujo. La propia guía de Microsoft pide dar por hecho que toda automatización puede fallar, y anticipar el mantenimiento del servicio de destino, cambios en la API, cambios de contraseña o interrupciones momentáneas de red2. En la práctica, pensar en las siguientes cuatro categorías determina directamente cómo actuar.

Categoría Ejemplo típico ¿Se soluciona con reintento? Dirección de la respuesta
Fallo temporal Corte momentáneo o mantenimiento del destino, limitación de tráfico (429), error de servidor (5xx) Se suele resolver Dejarlo en manos del reintento estándar (capítulo 3)
Causado por los datos Valores vacíos o formatos no previstos, ID inexistente en el destino de referencia (400/404) No se resuelve Capturar con Try-Catch y notificar (capítulo 4), validación en el origen de los datos
Permisos o autenticación caducados Caducidad de la conexión, cambio de contraseña, baja del responsable o cuenta deshabilitada No se resuelve Requiere volver a autenticarse. Detección y notificación (capítulo 5), diseño de cómo se gestionan las conexiones
Cambio de especificación Cambio de nombre de columna en SharePoint, cambio de versión de la API de destino, cambio de campos del formulario No se resuelve Requiere modificar el flujo. Gestión de cambios y notificación

De estas cuatro, la más problemática en la práctica es la de permisos o autenticación caducados, porque no solo fallan las acciones del flujo: falla el propio disparador. Como ejemplo típico de un disparador que falla con un error de la serie 4xx, la guía oficial de solución de problemas menciona el cambio (caducidad) de la contraseña usada en la conexión. Cuando el disparador falla, el flujo ni siquiera llega a iniciarse, por lo que ni una fila de «error» queda registrada en el historial de ejecuciones, y darse cuenta del problema se retrasa todavía más9. Como la conexión está vinculada al usuario individual que la creó, también ocurren incidentes en los que varias conexiones se cortan a la vez por la baja o el traslado del responsable. Este aspecto organizativo se trata en detalle en «Cómo evitar la dependencia de una sola persona en Power Automate ── para que el flujo no se detenga cuando quien lo creó se va».

Otra cosa que conviene saber es que dejar los fallos sin atender puede provocar que se detenga el propio flujo. Un flujo cuyo disparador o acciones siguen fallando se desactiva automáticamente a los 14 días, y uno sometido a una limitación de tráfico continua también se desactiva a los 14 días. Un flujo que no se disparó en 90 días también puede desactivarse (si su propietario no tiene una licencia premium o de capacidad)1. Además, por infracción de una política de DLP (Data Loss Prevention, prevención de pérdida de datos: una barrera de protección con la que el administrador restringe qué conectores se pueden usar y en qué combinaciones, para evitar que los datos de la organización salgan al exterior sin querer; el nombre oficial actual es «directivas de datos»)10 o por fallos repetidos, un flujo puede quedar en estado «suspendido» (suspended)11. Un cambio en una política de DLP surte efecto de inmediato y detiene los flujos sin previo aviso, así que, cuando varios flujos se rompen al mismo tiempo, la primera sospecha razonable es un cambio de política11. Una parte de los casos de «el flujo que funcionaba estaba detenido» no se debe a un fallo técnico, sino a este comportamiento del sistema.

3. Entender el reintento estándar

Las acciones de Power Automate (cuya base es Azure Logic Apps) incorporan una directiva de reintento desde el principio. Conocer con precisión esta especificación permite decidir si conviene añadir una configuración de reintento propia o si el reintento simplemente no va a resolver el problema.

Qué se reintenta y cuándo

La directiva de reintento actúa cuando la solicitud de una acción (o de un disparador) agota el tiempo de espera, o falla con una respuesta 408 (tiempo de espera de la solicitud agotado), 429 (demasiadas solicitudes = limitación de tráfico) o 5xx (error de servidor)3. La directiva predeterminada es de retroceso exponencial (reintenta alargando el intervalo de forma exponencial), y en Power Automate el número y el intervalo predeterminados dependen del perfil de rendimiento del flujo (en la práctica, el nivel de licencia)1.

Perfil de rendimiento Licencias principales asociadas Reintento predeterminado
Low Planes de Microsoft 365, plan gratuito, etc. Hasta 2 veces. El intervalo se alarga en pasos de unos 5 minutos, y el último reintento llega a un intervalo de unos 10 minutos
Medium / High Power Automate Premium, licencias Process, etc. Hasta 12 veces. Parte de 7 segundos y se alarga exponencialmente, hasta llegar a un intervalo de aproximadamente 1 hora en el último reintento

Es decir, incluso con la misma definición de flujo, la «resistencia frente a fallos temporales» varía según la licencia del propietario. El perfil no solo afecta al número de reintentos, sino también al límite diario de solicitudes, así que conviene consultar también «Licencias de Power Automate y el límite entre conectores estándar y premium» para entender los niveles de licencia.

La directiva de reintento se puede cambiar desde la configuración de la acción. Hay cuatro tipos: predeterminado, ninguno, intervalo fijo e intervalo exponencial, y se puede especificar explícitamente el número de reintentos y el intervalo. Los límites de configuración son 90 reintentos como máximo, un intervalo mínimo de 5 segundos y un retraso máximo de 1 día31. Las pautas de codificación de Microsoft recomiendan el intervalo exponencial por encima del intervalo fijo para recuperarse de fallos temporales, precisamente para no seguir golpeando el servicio de destino con intervalos cortos y así no entorpecer su propia recuperación4.

Lo que el reintento resuelve y lo que no

Situación ¿Se resuelve con reintento?
Corte momentáneo o tiempo de espera agotado en el destino (408/5xx) Se suele resolver. Basta con la configuración predeterminada
Limitación de tráfico (429) Puede resolverse si el intervalo se alarga. Pero un 429 constante es un problema de diseño (hay que reducir el número de solicitudes)
Datos inválidos (400) o recurso inexistente (404) No se resuelve. Se obtiene el mismo error por más intentos que se hagan
Error de autenticación (401/403) o conexión caída No se resuelve. Requiere volver a autenticarse, una operación fuera del flujo
Fallo de negocio (rechazo de una aprobación, falta de existencias, etc.) No es un error HTTP, así que directamente no es objeto de reintento. Se gestiona con una bifurcación del flujo

Conviene tener presente que el reintento también consume solicitudes (solicitudes de Power Platform). Cada ejecución de una acción cuenta como una solicitud, tanto si tiene éxito como si falla, y lo mismo ocurre con las solicitudes de reintento y de paginación1. Ajustar la configuración para aumentar el número de reintentos frente a un 429 puede incluso agravar la limitación de tráfico, así que antes de reforzar el reintento conviene plantearse primero si es posible reducir el número de llamadas en sí.

4. El patrón Try-Catch-Finally ── ámbitos y Configuración de ejecución posterior

Los fallos que el reintento no resuelve se capturan y procesan dentro del propio flujo. Power Automate no tiene una sintaxis try-catch como tal, pero combinando un ámbito (Scope) con la Configuración de ejecución posterior (run after en la interfaz en inglés) se puede reproducir la misma estructura. Es un patrón consolidado que las propias pautas de codificación de Microsoft recomiendan4.

La base de este mecanismo es la Configuración de ejecución posterior. Al terminar, cada acción queda en uno de estos estados: correcto (Succeeded), con error (Failed), omitido (Skipped) o tiempo agotado (TimedOut), y de forma predeterminada la acción siguiente solo se ejecuta «si la acción anterior se ha realizado correctamente». Esta condición se puede cambiar acción por acción, de modo que se pueden crear bifurcaciones que se ejecuten «si ha fallado» o «si se ha agotado el tiempo de espera»3.

El lugar donde se configura esto es difícil de encontrar a primera vista. En el diseñador, al abrir el menú de tres puntos («…») de la acción (o el ámbito) en cuestión y elegir «Configuración de ejecución posterior», aparece un panel con casillas para los cuatro estados de cada una de las acciones inmediatamente anteriores11. Ahí se marcan los estados necesarios. Un detalle a tener en cuenta: como siempre debe quedar al menos un estado seleccionado, hay que marcar primero el otro estado que se necesite y solo después desmarcar el predeterminado «si se ha realizado correctamente»3. Además, la Configuración de ejecución posterior no se limita a «la acción inmediatamente anterior»: se pueden especificar varias acciones precedentes y asignar un estado a cada una3.

Al aplicar esto a un ámbito, se obtiene un Try-Catch-Finally. Como un ámbito consolida en un único estado el resultado de todas las acciones que contiene, una configuración del tipo «si algo falla dentro del ámbito Try, ejecutar el ámbito Catch» resulta muchísimo más fácil de mantener que ir configurando la condición acción por acción34.

ÉxitoError / tiempo de espera agotadoNoDisparadorÁmbito TryEl procesamiento principal va aquíÁmbito FinallyConfiguración de ejecución posterior: éxito, error, omitido y tiempo agotado, todosÁmbito CatchConfiguración de ejecución posterior: si falla o si se agota el tiempoExtraer la acción fallida y el motivocon la función result y Filtrado de matrizNotificar al responsable por Teams o correonombre del flujo, paso fallido, detalle del error, URL de ejecuciónTareas de limpieza y actualización de la columna de estado del registro¿Pasó por Catch?TerminateEstado: Failed, para finalizar la ejecuciónFinalización correcta

Hay cuatro puntos clave en cómo construir esta estructura.

  • En la Configuración de ejecución posterior del ámbito Catch, se eligen tanto «si ha fallado» como «si se ha agotado el tiempo de espera», y se desmarca el «si se ha realizado correctamente» predeterminado. Si solo se elige «si ha fallado», se cuelan los tiempos de espera agotados de acciones en espera de aprobación o con retraso3.
  • Dentro de Catch se extrae el contenido del fallo. La función result('nombre del ámbito Try') devuelve, en forma de matriz, el resultado (estado, entradas y salidas, cuerpo del error) de las acciones que están directamente dentro del ámbito; si con «Filtrado de matriz» (Filter array) se filtra por las que tienen estado Failed o TimedOut, se puede incluir en la notificación el nombre de la acción fallida y el mensaje de error34. Si se filtra solo por Failed, cuando se entra a Catch a través de un tiempo de espera agotado el resultado de la extracción queda vacío y falta en la notificación justamente el paso que falló. Conviene además extraer el ID de ejecución con la función workflow() y construir la URL de acceso directo al historial de ejecuciones: esto facilita enormemente la investigación (las expresiones se detallan en el apartado siguiente)4.
  • En la Configuración de ejecución posterior del ámbito Finally se eligen los cuatro estados. Aquí se colocan las tareas de limpieza que deben ejecutarse siempre, tanto si hubo éxito como si hubo error (eliminar archivos temporales, actualizar la columna de estado del registro, etc.).
  • La ejecución que falló debe terminarse al final como «con error» mediante la acción Terminate. Este es el punto que más se suele olvidar. Si Catch se completa con normalidad, la ejecución del flujo en su conjunto queda como si la última acción hubiera terminado con éxito, y así se registra «correcto» en el historial de ejecuciones. Es decir, si solo se notifica y ahí termina todo, el fallo deja de verse en el historial de ejecuciones y se escapa del monitoreo y de cualquier recuento posterior. Si se termina con Terminate estableciendo el estado Failed y el mensaje de error, quedará registrado como error también en el historial de ejecuciones43. Ahora bien, no hay que colocar Terminate directamente al final del ámbito Catch. Terminate finaliza de inmediato toda la ejecución en ese momento, por lo que el ámbito Finally posterior no llegaría a ejecutarse, y precisamente las tareas de limpieza que hacen falta en caso de error se saltarían. Como en el diagrama, en Catch conviene limitarse a activar una marca de error (variable) y notificar; después de pasar por la limpieza de Finally, se evalúa esa marca y, solo si hubo error, se termina con Terminate.

Cabe señalar que la Configuración de ejecución posterior también es la pieza central de las bifurcaciones por tiempo de espera agotado (recordatorios, escalamiento) en los flujos de aprobación. La forma concreta de construirlo se trata en «Cómo crear un flujo de aprobación en Power Automate ── digitalizar solicitudes y aprobaciones que hoy van en papel o por correo».

El contenido de Catch ── extraer con expresiones la acción fallida y la URL de ejecución

Este es el punto crítico de la implementación, así que se detallan también las expresiones. Suponiendo que el ámbito Try se llame Try, la configuración de «Filtrado de matriz» (Filter array) queda así. La condición se escribe directamente como expresión cambiando a «Editar en modo avanzado»34.

Origen (From):  @result('Try')
Condición (modo avanzado): @or(equals(item()['status'], 'Failed'), equals(item()['status'], 'TimedOut'))

De cada elemento individual que devuelve result() se pueden extraer los siguientes valores. Si se incluyen estos cuatro en el cuerpo de la notificación, se puede tener una idea de lo ocurrido antes incluso de abrir el historial de ejecuciones3.

Información que se desea obtener Expresión
Nombre de la acción fallida item()['name']
Estado (Failed / TimedOut) item()['status']
Código de error item()['code']
Cuerpo de la respuesta (mensaje de error) item()['outputs']['body']

El enlace directo al historial de ejecuciones se construye a partir de la función workflow(). Esta función devuelve un objeto con el ID del flujo (name), el nombre del entorno (tags.environmentName), el nombre lógico del flujo (tags.logicAppName), el ID de la ejecución (run.name) y otros datos, de modo que la URL adopta la siguiente forma4.

concat('https://make.powerautomate.com/environments/', workflow()?['tags']?['environmentName'],
       '/flows/', workflow()?['tags']?['logicAppName'],
       '/runs/', workflow()?['run']?['name'])

La documentación oficial explica el procedimiento analizando la salida de workflow() con «Análisis de JSON» (Parse JSON) y después construyendo la URL con la acción «Crear» (Compose)4. El resultado es el mismo en ambos casos, pero la URL del portal puede cambiar, así que conviene hacer clic una vez en el enlace recién generado para confirmar que abre el historial de ejecuciones esperado. La misma documentación advierte también que registrar demasiados datos de registro propios resulta contraproducente, porque infla el número de acciones y el tiempo de ejecución4. En la práctica, lo más razonable es limitarse a estos cuatro datos: nombre del flujo, acción fallida, error y URL de ejecución.

5. Cómo detectar los fallos ── notificación y visibilidad

Por más que se implemente el manejo de errores, de nada sirve si nadie se entera del fallo. El «mecanismo para detectarlo» se diseña en varias capas, sin depender de la notificación predeterminada.

Entender correctamente el correo de notificación de fallos predeterminado

Power Automate cuenta con un mecanismo que envía una notificación por correo en caso de fallo, pero confiar en él sin conocer sus especificaciones deja demasiados huecos. Hay dos tipos de notificación5.

  • Alerta de error por ejecución: se envía justo después de que una ejecución falla, pero solo cuando el fallo se clasifica como uno «con una solución conocida», como una conexión caída, una limitación de tráfico o un error conocido de un conector. No se envía ante un fallo genérico de una acción. Los destinatarios son el propietario y los copropietarios (no incluye a los usuarios de solo ejecución), y no se envía a los administradores. Además, una vez enviada, existe un período de enfriamiento de 28 días para ese mismo flujo, durante el cual los fallos posteriores no generan alertas adicionales. Tampoco está habilitada de forma predeterminada en todos los flujos: hay que comprobarlo en la configuración de cada flujo5.
  • Resumen semanal de fallos: una vez por semana se envía un resumen de los fallos ocurridos en distintos entornos. Aquí sí se incluyen los fallos genéricos que no generan la alerta por ejecución5.

Además, para ciertos errores se envía al propietario un correo de «sugerencias de reparación» con los pasos para solucionarlos (se puede desactivar por flujo)7. En resumen, la notificación predeterminada es un mecanismo con el que «se puede detectar la primera vez que se cae una conexión, pero se cuelan con facilidad los fallos causados por los datos de negocio y los fallos posteriores al primero». Para los flujos importantes, hay que considerar obligatoria una notificación propia desde el bloque Catch descrito en el capítulo 4.

Diseño de la notificación desde Catch ── cuando el propio flujo de notificación falla

La notificación propia también tiene puntos de diseño a considerar.

  • No dirigir la notificación a una persona individual. Si se envía al responsable a título personal, con su ausencia o baja nadie llega a recibirla. La propia documentación oficial recomienda enviarla a un buzón compartido o a un canal de Teams11.
  • Separar el canal de notificación del procesamiento principal. Un incidente habitual es el «efecto dominó»: la conexión de Outlook se cae, el flujo falla, y como la notificación de fallo usa esa misma conexión de Outlook, tampoco se puede enviar. En un fallo causado por la caducidad de la autenticación, la acción de notificación que usa la misma conexión también falla al mismo tiempo. Usar para la notificación un conector y una conexión distintos de los del procesamiento principal (por ejemplo, una publicación en Teams), o separarla en un pequeño flujo dedicado solo a notificar, reduce el riesgo de este efecto dominó. Aun así, no se puede construir «una notificación de la notificación» de forma indefinida, así que, como última línea de defensa, se añade la revisión periódica del apartado siguiente.
  • Incluir en la notificación toda la información necesaria para investigar: el nombre del flujo, el nombre de la acción fallida, el mensaje de error y el enlace directo al historial de ejecuciones. Sin esto, aunque llegue la notificación no se sabrá más que «algo falló», y tiende a dejarse sin atender4.

Visibilidad y revisión periódica

  • Comprobador de flujos (Flow Checker): detecta errores y advertencias en la definición del flujo antes de guardarlo. Conviene acostumbrarse a revisarlo una vez terminado el desarrollo12.
  • Revisión periódica del historial de ejecuciones: el historial de ejecuciones del flujo solo se muestra durante 28 días de forma predeterminada6. Los flujos incluidos en una solución pueden conservar los metadatos del historial de ejecuciones en Dataverse, pero ahí la retención predeterminada también es de 28 días, y ampliarla es una configuración que corresponde al administrador13. Para los flujos en producción, se recomienda revisar aproximadamente una vez por semana no solo los fallos, sino también las «ejecuciones en estado cancelado» (a veces causadas por el control de concurrencia) y las «caídas bruscas en el número de ejecuciones» (indicio de que el disparador no está funcionando)11.
  • Monitoreo centralizado del administrador: para ver absolutamente todos los fallos, incluidos los que no generan la alerta por ejecución, la opción más completa es Monitor en el Centro de administración de Power Platform. Permite consultar el número de fallos y el detalle de los errores por flujo y por entorno5.

En el caso de los flujos programados, también hace falta vigilar si «llegó siquiera a iniciarse». El diseño de la ejecución programada, incluyendo la determinación de días hábiles y el procesamiento de fin de mes, se trata en «Flujos programados y diseño de días hábiles en Power Automate».

6. Reejecución e idempotencia ── construir un flujo que «no se rompa aunque se ejecute dos veces»

Responder a un fallo no termina con detectarlo. Hace falta, además, la operación de «rehacer lo que falló» junto con un diseño que garantice que «rehacerlo no rompe nada».

Especificaciones del reenvío (resubmit)

Una ejecución que falló se puede rehacer desde el historial de ejecuciones mediante Reenviar (Resubmit). Es una operación que vuelve a ejecutar el flujo con los mismos datos del disparador: si se trata de un fallo temporal (500/502, etc.) basta con reenviar tal cual, y si la causa es un error en la definición del flujo, corrigiendo y guardando el flujo y reenviando después, la reejecución se hará con la definición ya corregida7. Desde la lista del historial de ejecuciones se pueden reenviar en conjunto hasta 20 ejecuciones a la vez, lo cual sirve para recuperarse de un fallo masivo. En los flujos de inicio manual (disparador instantáneo), las propias ejecuciones se pueden reenviar en cualquier momento, pero reenviar una ejecución iniciada por otro usuario requiere que el administrador lo habilite en la configuración del inquilino14.

Lo importante aquí es que el reenvío vuelve a ejecutar el flujo desde el principio. Si se reenvía una ejecución que falló en el paso 8 de 10, los pasos del 1 al 7, que ya habían tenido éxito, también se vuelven a ejecutar. De aquí surgen incidentes como «el correo ya se había enviado y se volvió a enviar» o «se crearon dos filas iguales en el registro».

Idempotencia ── un diseño seguro frente a la ejecución doble

Por eso conviene incorporar desde el principio un diseño idempotente: uno en el que, con la misma entrada, el resultado sea siempre el mismo sin importar cuántas veces se ejecute. Es el núcleo del diseño de manejo de errores, porque protege no solo frente al reenvío, sino también frente al inicio duplicado del disparador y la ejecución concurrente.

  • Mantener una marca de «ya procesado». Se añade una columna de «estado» (sin procesar / en proceso / procesado) al registro, por ejemplo una lista de SharePoint, y al principio del flujo se comprueba el estado: si ya está procesado, se termina ahí mismo, y al terminar el procesamiento se actualiza el estado. Con esto, aunque se reenvíe, no se produce un procesamiento duplicado. Ahora bien, la marca solo funciona si también se decide el orden de la actualización. Los efectos secundarios hacia el exterior, como el envío de un correo o el registro en un sistema central, se ejecutan justo después de actualizar a «en proceso», y solo se pasa a «procesado» una vez completados. Una ejecución que falla después del efecto secundario pero antes de actualizar la marca queda en «en proceso», un estado en el que no se sabe si el efecto secundario llegó a completarse. Reenviar mecánicamente esta fila puede provocar un envío duplicado, así que las filas en «en proceso» se excluyen de la reejecución automática, y se deja que una persona las compare con el resultado real del envío o del registro y las devuelva a «procesado» o a «sin procesar». Solo las filas que quedaron detenidas en «sin procesar» se pueden reejecutar con tranquilidad.
  • Usar «actualizar si existe, crear si no» (upsert) en lugar de «crear» sin más. Se busca la fila existente con una clave única (número de pedido, ID de solicitud, etc.) y se bifurca: si hay coincidencia, se actualiza; si no la hay, se crea. Un «Crear elemento» incondicional va acumulando filas duplicadas cada vez que se reejecuta. Dicho de otro modo, los datos sin una clave única no se pueden hacer idempotentes, así que decidir la columna clave en la etapa de diseño del registro es un requisito previo.
  • Detener los inicios innecesarios con condiciones de disparador. Casos de inicio múltiple, como un flujo con el disparador «cuando se crea o modifica un elemento» que se reinicia a causa de su propia escritura de retorno, se detienen mediante condiciones de disparador (trigger conditions), no con una bifurcación condicional posterior. Un evento que no cumple la condición de disparador no llega a generar una ejecución, así que no consume ni recuento de ejecuciones ni de solicitudes8.

Una advertencia. Métodos como la marca de «ya procesado» o el upsert, que funcionan bajo el esquema de «comprobar y luego escribir», son eficaces frente a una repetición secuencial, como el reenvío, pero por sí solos no son una protección atómica. Si dos eventos de disparador duplicados se inician casi al mismo tiempo, puede darse una condición de carrera en la que ambas ejecuciones lean «sin procesar» y ambas avancen con el procesamiento. Para evitar de forma segura la duplicación en un flujo donde pueda haber inicios concurrentes, hay que combinar el enfoque anterior con el control de concurrencia del apartado siguiente, poniendo el grado de paralelismo en 1 para serializar la ejecución, o bien usar en el destino de almacenamiento un mecanismo que imponga una restricción de clave única (como una restricción de unicidad de base de datos) y así hacer que la creación duplicada falle en el momento de la escritura.

Control de concurrencia (concurrency control) y el compromiso con el orden

Junto con la ejecución doble, otro problema es el de la «concurrencia» y el «orden». De forma predeterminada, si se producen muchos eventos que cumplen la condición de disparador al mismo tiempo, el flujo se ejecuta en paralelo tantas veces como haga falta1. Cuando varias ejecuciones leen y escriben a la vez la misma fila de un registro, puede producirse una inconsistencia por lectura de un valor obsoleto y su posterior sobrescritura (lectura sucia, dirty read)15.

Al activar el Control de concurrencia (Concurrency Control) en la configuración del disparador, se puede especificar el número de ejecuciones en paralelo (grado de paralelismo) entre 1 y 100. Con el grado de paralelismo en 1, solo hay una ejecución a la vez, con lo que el procesamiento se acerca a respetar el orden115. Sin embargo, este interruptor tiene advertencias importantes.

  • Una vez activado, no se puede desactivar. La única forma de volver a desactivarlo es eliminar el disparador y volver a crearlo1. Como el control de concurrencia es irreversible, se recomienda aplicarlo únicamente a flujos con pocas acciones (extrayendo un flujo secundario si hace falta)15.
  • Aparece el riesgo de perder eventos. Con el control de concurrencia activado, el número de ejecuciones que pueden quedar en espera es de hasta «10 + grado de paralelismo»; los disparadores que llegan mientras se está en ese límite se reintentan del lado del conector, pero si se supera el límite durante mucho tiempo, existe la posibilidad de que la ejecución nunca llegue a producirse. La documentación oficial indica expresamente que, en los flujos donde se necesita que todos los disparadores lleguen sin falta a ejecutarse, el control de concurrencia debe dejarse desactivado1. Si el historial de ejecuciones está lleno de ejecuciones en estado cancelado, esta configuración puede ser la causa11.

Es decir, «respetar el orden» y «no perder eventos» son un compromiso mutuamente excluyente. Serializar con un grado de paralelismo de 1 es eficaz para procesos con poco volumen donde el orden importa (como la numeración correlativa de un registro), pero no conviene aplicarlo sin más a procesos que reciben una gran cantidad de eventos en horas pico. Si se necesitan estrictamente tanto el orden como la cobertura total, se entra, como se explica en el capítulo 8, en un terreno que conviene diseñar fuera de Power Automate.

7. Lista de verificación de diseño antes de pasar a producción

Antes de poner un flujo nuevo en producción, conviene confirmar como mínimo lo siguiente. Lo ideal sería tenerlo todo listo desde el primer día, pero para bajar la barrera de entrada se ha dividido en dos niveles: «imprescindible» (sin esto, los incidentes no se ven) y «si hay margen» (para completar dentro del primer mes de operación).

# Nivel Elemento a confirmar Capítulo relacionado
1 Imprescindible ¿Se ha previsto qué ocurre en este flujo para cada una de las cuatro categorías de fallo (temporal / datos / autenticación caducada / cambio de especificación)? Capítulo 2
2 Si hay margen ¿Basta con la directiva de reintento predeterminada? Si el destino suele devolver 429, ¿se puede reducir el número de solicitudes en sí? Capítulo 3
3 Imprescindible ¿Está el procesamiento principal reunido en el ámbito Try? ¿Se han elegido tanto «error» como «tiempo agotado» en la Configuración de ejecución posterior de Catch? Capítulo 4
4 Imprescindible ¿Está el orden dispuesto para terminar con Terminate (estado: Failed) según la marca de error, y solo después de completar la limpieza de Finally? ¿No se está silenciando el fallo? Capítulo 4
5 Imprescindible ¿Se ha construido una notificación de fallo propia? ¿El destinatario es un buzón compartido o un canal de Teams? ¿Usa un canal distinto del procesamiento principal? Capítulo 5
6 Si hay margen ¿Incluye la notificación el nombre del flujo, la acción fallida, el detalle del error y la URL de ejecución? Capítulo 5
7 Si hay margen ¿Se ha decidido quién hace la revisión semanal del historial de ejecuciones (fallos, cancelaciones, caídas bruscas del número de ejecuciones)? Capítulo 5
8 Imprescindible ¿Es seguro aunque se reenvíe? ¿Es idempotente gracias a la marca de «ya procesado» o al upsert? ¿Existe una clave única? Capítulo 6
9 Imprescindible ¿Se detiene el auto-disparo o el inicio múltiple mediante condiciones de disparador? Capítulo 6
10 Si hay margen Si se usa el control de concurrencia, ¿se entiende que es irreversible y el riesgo de perder eventos que conlleva? Capítulo 6
11 Si hay margen ¿De quién es la conexión? ¿Se ha configurado un copropietario, de modo que se pueda volver a autenticar o corregir aunque el responsable esté ausente? Capítulo 2
12 Si hay margen ¿Hay alguna forma de darse cuenta si el flujo se desactiva automáticamente (por ejemplo, por 14 días de fallos consecutivos)? Capítulos 2 y 5

Puede parecer que doce elementos son muchos, pero para el primer día de producción solo hacen falta los seis de la categoría «imprescindible», y más de la mitad de ellos son cosas que basta con pensar una sola vez, al principio. Los seis elementos de «si hay margen» tampoco significan que se puedan dejar de lado sin más: son los que se pueden completar con calma una vez que el flujo ya está funcionando. Por el contrario, «añadir esto después» a un flujo que ya se puso en producción saltándose estos pasos casi nunca llega a hacerse —por el miedo a tocar algo que ya funciona— y termina desembocando en un incidente.

8. Hasta dónde llegar con Power Automate

Si se lleva el manejo de errores hasta sus últimas consecuencias, empiezan a aparecer requisitos que superan el alcance de Power Automate. A continuación, algunos criterios orientativos para trazar esa línea.

Situación Criterio
Un proceso en el que, si falla, basta con notificar y que una persona lo revise y reenvíe Power Automate es suficiente. Los patrones de este artículo bastan
Se actualizan varios sistemas en secuencia y, si falla a mitad de camino, hay que deshacer lo ya actualizado (transacción compensatoria) Implementarlo dentro del flujo tiende a complicarse mucho. Es terreno de preparar una API que reciba el procesamiento como un todo, o de desarrollo por encargo
Se exigen a la vez garantía de orden, exclusión mutua y cero pérdida de eventos (numeración, asignación de inventario, integración contable, etc.) Considerando el compromiso del control de concurrencia (capítulo 6), es más seguro el terreno de desarrollo donde se pueden usar colas o transacciones de base de datos
Son imprescindibles las pruebas automatizadas (incluido el comportamiento ante fallos), el historial de cambios y la revisión de código Las pruebas unitarias de una definición de flujo son difíciles. Conviene pasar a PowerShell o .NET, que se pueden gestionar con Git
Se procesan decenas de miles de registros cada vez y se quiere reprocesar solo las filas que fallaron Los bucles de un flujo no son adecuados para grandes volúmenes de datos. Hace falta un diseño de procesamiento por lotes

Como criterio general, se puede pensar así: mientras el procedimiento de recuperación en caso de fallo se pueda explicar de palabra, es terreno de Power Automate; en cuanto ya no se pueda explicar sin dibujar un diagrama, es terreno de desarrollo. En particular, los procesos que requieren una transacción compensatoria (ya se registró en el sistema de la empresa A, falló en el de la empresa B, ¿se deshace lo de A?) son más complejos de lo que aparenta el flujo, y no se resuelven con Terminate y una notificación. El criterio para decidir entre Power Automate, PowerShell y el Programador de tareas se organiza en «Power Automate frente a PowerShell y el Programador de tareas: cuándo usar cada uno».

9. Resumen

«El flujo que funcionaba estaba detenido» no es mala suerte: es, casi siempre, un problema de diseño. Un flujo siempre acaba fallando en algún momento. De las cuatro categorías de fallo, el reintento solo se ocupa de los fallos temporales; los causados por los datos, por la autenticación caducada o por un cambio de especificación solo se pueden atrapar con un mecanismo de varias capas: captura con Try-Catch, registro con Terminate, notificación propia y revisión semanal del historial de ejecuciones. El correo de notificación de fallos predeterminado es un mecanismo limitado, condicional y con un período de enfriamiento de 28 días, y una operación que dependa de él siempre acabará dejando escapar algo.

Y el núcleo de la preparación frente a los fallos no es tanto la notificación como la idempotencia. Si con la marca de «ya procesado» y el upsert se logra una forma que «no se rompe aunque se ejecute dos veces», el reenvío y la duplicación del disparador dejan de dar miedo, y la recuperación se reduce a «elegir lo que falló y reenviarlo». Por el contrario, para los procesos que requieren una transacción compensatoria o una garantía estricta de orden, a la larga sale más barato no forzar la implementación dentro de Power Automate y decidir separarlos hacia el terreno de desarrollo. Justo el día en que el flujo empiece a funcionar es el mejor momento para recorrer esta lista de verificación una vez.

Artículos relacionados

Áreas de consultoría relacionadas

KomuraSoft LLC se ocupa desde la revisión del manejo de errores y el diseño operativo de flujos de Power Automate, hasta la sistematización de requisitos de garantía de orden y transacciones que ya no caben en un flujo.

Referencias

  1. Microsoft Learn, Limits of automated, scheduled, and instant flows. Sobre que la directiva de reintento predeterminada varía según el perfil de rendimiento (Low: hasta 2 veces, en pasos de unos 5 minutos; Medium/High: hasta 12 veces, desde 7 segundos hasta cerca de 1 hora), los límites de la configuración de reintento (90 veces, intervalo mínimo de 5 segundos, retraso máximo de 1 día), el período de ejecución de 30 días, que los flujos que siguen fallando o sometidos a limitación de tráfico continua se desactivan a los 14 días, que un flujo no disparado en 90 días puede desactivarse, que el control de concurrencia está desactivado de forma predeterminada con un grado de paralelismo de 1 a 100 (25 de forma predeterminada al activarlo) y que no se puede revertir salvo eliminando y recreando el disparador, que el número de ejecuciones en espera es de «10 + grado de paralelismo» con la posibilidad de que los disparadores en exceso no lleguen a ejecutarse, y que todas las acciones —éxito y error, incluidos reintentos y paginación— cuentan para el número de solicitudes.  2 3 4 5 6 7 8 9 10 11

  2. Microsoft Learn, Reducing risk and planning for error handling. Sobre la premisa de que toda automatización puede fallar, los factores de fallo al usar un conector (interrupción por mantenimiento, defectos de software, cambios de versión de la API), los factores de fallo comunes a cualquier automatización (cambio de contraseña, interrupciones momentáneas de red) y la existencia de la directiva de reintento.  2

  3. Microsoft Learn, Handle workflow errors and exceptions in Azure Logic Apps. Sobre que la directiva de reintento se aplica a las respuestas 408, 429 y 5xx y a los tiempos de espera agotados; que la directiva predeterminada es de intervalo exponencial; los tipos de reintento (predeterminado/ninguno/fijo/exponencial); los cuatro estados de la Configuración de ejecución posterior (run after) —Succeeded/Failed/Skipped/TimedOut—; que hay que elegir otro estado antes de quitar el predeterminado (siempre debe quedar al menos un estado seleccionado); que se puede asignar un estado a cada una de varias acciones precedentes; la evaluación de estado de los ámbitos y la captura de excepciones mediante run after; la extracción de las acciones fallidas con la función result() y el filtrado de matriz (@result('nombre del ámbito') y equals(item()['status'], 'Failed')); las propiedades que tiene cada elemento de result() (name, status, code, outputs, clientTrackingId, etc.); y la evaluación de estado según la cual, si una rama no termina en error, la ejecución completa no se considera fallida.  2 3 4 5 6 7 8 9 10 11 12 13 14

  4. Microsoft Learn, Employ robust error handling. Sobre el patrón Try-Catch con ámbitos, la bifurcación de errores en la Configuración de ejecución posterior, el filtrado de result() con Filter array dentro del ámbito Catch, la recomendación del reintento exponencial, terminar la ejecución como fallida estableciendo el estado Failed con la acción Terminate, el esquema JSON que devuelve la función workflow() (name, tags.environmentName, tags.logicAppName, run, etc.) y la construcción de la URL del historial de ejecuciones con las acciones Parse JSON y Compose, la advertencia de que registrar demasiados datos de registro propios afecta al número de acciones y al rendimiento, y la recomendación de registrar y notificar los errores.  2 3 4 5 6 7 8 9 10 11 12 13

  5. Microsoft Learn, Understand flow failure notifications. Sobre que la alerta de error por ejecución se limita a los «fallos con una solución conocida» (conexión caída, limitación de tráfico, etc.), que los destinatarios son el propietario y los copropietarios y que no se envía a los usuarios de solo ejecución ni a los administradores, el período de enfriamiento de 28 días para el mismo flujo, que la alerta por ejecución no está habilitada de forma predeterminada en todos los flujos, el resumen semanal de fallos, y que en Monitor, dentro del Centro de administración de Power Platform, se pueden consultar todos los fallos.  2 3 4 5

  6. Microsoft Learn, Missing runs or triggers history for a flow. Sobre que los datos del historial de ejecuciones del flujo solo se conservan durante 28 días de forma predeterminada y dejan de mostrarse en la página del historial de ejecuciones.  2

  7. Microsoft Learn, Troubleshoot a cloud flow. Sobre que el correo de «sugerencias de reparación» (repair tips) se envía al propietario y se puede desactivar por flujo, el procedimiento para identificar el paso fallido a partir del historial de ejecuciones de 28 días, el reenvío ante errores temporales como 500/502, y que reenviar tras corregir y guardar el flujo hace que la reejecución use la configuración ya corregida.  2 3

  8. Microsoft Learn, Customize your triggers with conditions. Sobre que, con una condición de disparador, un evento que no la cumple no llega a generar una ejecución, mientras que descartarlo con una bifurcación condicional posterior sí consume una ejecución y una solicitud de API.  2

  9. Microsoft Learn, “There is a problem with the flow’s trigger” error shown in a flow’s run history. Sobre que, si el propio disparador falla, el flujo no llega a ejecutarse; que un fallo del disparador de la serie 4xx es un problema que debe corregir el usuario, como un cambio en la conexión (por ejemplo, la caducidad de la contraseña); y que uno de la serie 5xx es un problema temporal del sistema. 

  10. Microsoft Learn, Data policies. Sobre que las directivas de datos (políticas de DLP) son una barrera de protección con la que el administrador controla el acceso a los conectores para reducir el riesgo de que los datos de la organización se expongan sin querer, y que una app o un flujo que infringe una política queda en estado suspendido o en cuarentena y deja de funcionar. 

  11. Microsoft Learn, Fix connection failures in cloud flows. Sobre el estado «suspendido» (suspended) del flujo, la bifurcación paralela de notificación de fallos mediante la Configuración de ejecución posterior y su procedimiento (abrir «Configuración de ejecución posterior» desde el «…» de la acción y elegir solo «si ha fallado»), la recomendación de enviar la notificación de los flujos importantes a un buzón compartido o a un canal de Teams, la revisión semanal del historial de ejecuciones (fallos, cancelaciones, caídas bruscas del número de ejecuciones), que las ejecuciones en estado cancelado pueden deberse a la configuración de concurrencia, que un cambio en una política de DLP se aplica de inmediato sin previo aviso y puede ser la causa de que varios flujos se rompan a la vez, y que las conexiones de entidad de servicio no se ven afectadas por un cambio de contraseña ni por una baja de personal.  2 3 4 5 6

  12. Microsoft Learn, Tools to test your automation. Sobre la detección de errores al crear el flujo mediante el Comprobador de flujos, las sugerencias de reparación, y la configuración de una notificación de error propia mediante la Configuración de ejecución posterior. 

  13. Microsoft Learn, Manage cloud flow run history in Dataverse. Sobre que el historial de ejecuciones de los flujos compatibles con soluciones se guarda en la tabla FlowRun de Dataverse, y que el período de retención predeterminado es de 28 días, aunque el administrador puede cambiarlo. 

  14. Microsoft Learn, Cancel or resubmit flow runs in bulk. Sobre que desde el historial de ejecuciones se pueden reenviar o cancelar hasta 20 ejecuciones a la vez, y que reenviar una ejecución de disparador instantáneo iniciada por otro usuario requiere habilitar la configuración del inquilino (Power Automate flow run resubmission). 

  15. Microsoft Learn, Optimize Power Automate triggers. Sobre que, de forma predeterminada, el disparador ejecuta en paralelo todas las ejecuciones que cumplen la condición; la inconsistencia por lectura sucia; que el control de concurrencia está desactivado de forma predeterminada; que con un grado de paralelismo de 1 solo hay una ejecución a la vez, lo cual es eficaz para procesos donde importa el orden; y que el control de concurrencia es irreversible, por lo que se recomienda aplicarlo a flujos con pocas acciones (flujos secundarios).  2 3

Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.

Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.

Preguntas frecuentes

Preguntas habituales en las consultas sobre el tema del artículo.

Si un flujo de Power Automate falla, ¿llega automáticamente un correo de notificación?
Solo de forma limitada. La alerta de error por ejecución se envía al propietario y a los copropietarios únicamente cuando el fallo se clasifica como uno «con una solución conocida» (por ejemplo, una conexión caída o una limitación de tráfico); no se envía ante un fallo genérico de una acción. Además, una vez enviada, existe un período de enfriamiento de 28 días para ese mismo flujo, durante el cual no llegan alertas adicionales. Tampoco está habilitada de forma predeterminada en todos los flujos. Para enterarse con seguridad, se recomienda incorporar en el bloque Catch una notificación propia hacia Teams o el correo electrónico.
¿Cuántas veces y con qué intervalos realiza Power Automate los reintentos estándar?
Cuando la solicitud de una acción agota el tiempo de espera o falla con una respuesta 408, 429 o de la serie 5xx, de forma predeterminada se reintenta automáticamente con un retroceso exponencial que va alargando el intervalo. El número de reintentos depende del perfil de rendimiento del flujo (en la práctica, el nivel de licencia): hasta 2 veces en perfiles bajos, como las licencias de Microsoft 365, y hasta 12 veces en perfiles medio y alto, como Power Automate Premium o las licencias Process. Desde la configuración de la acción se puede cambiar la directiva de reintento a «ninguno, intervalo fijo o intervalo exponencial», y se puede establecer un número de hasta 90 reintentos. Los errores originados por datos o configuración, como 400 o 404, no son objeto de reintento.
¿Cómo se vuelve a ejecutar (reenviar) una ejecución de flujo que falló?
Se abre la ejecución fallida desde el historial de ejecuciones y se elige «Reenviar»; así se vuelve a ejecutar con los mismos datos del disparador. Si la causa es un error en la definición del flujo, basta con corregir el flujo, guardarlo y luego reenviar: la reejecución se hará con el contenido ya corregido. Desde la lista del historial de ejecuciones se pueden reenviar en conjunto hasta 20 ejecuciones a la vez. El punto de atención es que el reenvío vuelve a ejecutar el flujo desde el principio, de modo que en una ejecución que había tenido éxito hasta cierto punto, los pasos ya completados se vuelven a ejecutar. Por eso es necesario contar con un diseño idempotente (marca de «ya procesado», escrituras que prioricen la actualización sobre la creación) para que el resultado no se corrompa aunque se ejecute dos veces.
¿Puede un flujo quedar deshabilitado sin que nos demos cuenta?
Sí, puede ocurrir. Un flujo cuyo disparador o acciones siguen fallando se desactiva automáticamente a los 14 días. Un flujo sometido a una limitación de tráfico continua se desactiva de la misma forma a los 14 días. Además, un flujo que no se ha disparado ni una sola vez en 90 días también puede desactivarse si su propietario no cuenta con una licencia premium o de capacidad. Como dejar los fallos sin atender conduce directamente a la detención del flujo, es fundamental incorporar en la operación un mecanismo para detectarlos y una revisión periódica del historial de ejecuciones (28 días de forma predeterminada).

Perfil del autor

Página de presentación del autor del artículo.

Go Komura

Representante de KomuraSoft LLC

Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.

Volver al blog