{
  "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
  "id": "error-handler",
  "name": "Error Handler Pattern",
  "description": "Robust error handling with retry logic, dead letter queue, and admin notifications. Use as a wrapper around failure-prone operations.",
  "category": "patterns",
  "tags": ["error-handling", "retry", "resilience", "patterns"],
  "parameters": {
    "maxRetries": {
      "type": "number",
      "description": "Maximum number of retry attempts",
      "required": false,
      "default": 3
    },
    "retryDelaySeconds": {
      "type": "number",
      "description": "Delay between retries in seconds",
      "required": false,
      "default": 30
    },
    "adminEmail": {
      "type": "string",
      "description": "Admin email for failure notifications",
      "required": true
    },
    "deadLetterListUrl": {
      "type": "string",
      "description": "SharePoint list URL for dead letter queue",
      "required": false
    },
    "flowName": {
      "type": "string",
      "description": "Name of this flow for logging",
      "required": true
    }
  },
  "connectionReferences": {
    "shared_office365": {
      "connectorId": "/providers/Microsoft.PowerApps/apis/shared_office365",
      "tier": "Standard",
      "description": "Office 365 for sending error notification emails"
    },
    "shared_sharepointonline": {
      "connectorId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline",
      "tier": "Standard",
      "description": "SharePoint for dead letter queue logging"
    }
  },
  "definition": {
    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
    "contentVersion": "1.0.0.0",
    "triggers": {
      "manual": {
        "type": "Request",
        "kind": "Http",
        "inputs": {
          "schema": {
            "type": "object",
            "properties": {
              "operationName": { "type": "string" },
              "payload": { "type": "object" },
              "correlationId": { "type": "string" }
            },
            "required": ["operationName", "payload"]
          }
        }
      }
    },
    "actions": {
      "Initialize_retry_count": {
        "type": "InitializeVariable",
        "inputs": {
          "variables": [{
            "name": "retryCount",
            "type": "Integer",
            "value": 0
          }]
        },
        "runAfter": {}
      },
      "Initialize_succeeded": {
        "type": "InitializeVariable",
        "inputs": {
          "variables": [{
            "name": "succeeded",
            "type": "Boolean",
            "value": false
          }]
        },
        "runAfter": {
          "Initialize_retry_count": ["Succeeded"]
        }
      },
      "Initialize_last_error": {
        "type": "InitializeVariable",
        "inputs": {
          "variables": [{
            "name": "lastError",
            "type": "String",
            "value": ""
          }]
        },
        "runAfter": {
          "Initialize_succeeded": ["Succeeded"]
        }
      },
      "Retry_loop": {
        "type": "Until",
        "expression": {
          "or": [
            { "equals": ["@variables('succeeded')", true] },
            { "greaterOrEquals": ["@variables('retryCount')", 3] }
          ]
        },
        "actions": {
          "Try_operation": {
            "type": "Scope",
            "actions": {
              "Execute_operation": {
                "type": "Compose",
                "inputs": {
                  "operation": "@{triggerBody()?['operationName']}",
                  "payload": "@{triggerBody()?['payload']}",
                  "attempt": "@{add(variables('retryCount'), 1)}"
                },
                "runAfter": {},
                "description": "Replace this with your actual operation"
              },
              "Mark_success": {
                "type": "SetVariable",
                "inputs": {
                  "name": "succeeded",
                  "value": true
                },
                "runAfter": {
                  "Execute_operation": ["Succeeded"]
                }
              }
            },
            "runAfter": {}
          },
          "Catch_error": {
            "type": "Scope",
            "actions": {
              "Capture_error": {
                "type": "SetVariable",
                "inputs": {
                  "name": "lastError",
                  "value": "@{coalesce(result('Try_operation')?[0]?['error']?['message'], 'Unknown error')}"
                },
                "runAfter": {}
              },
              "Increment_retry": {
                "type": "IncrementVariable",
                "inputs": {
                  "name": "retryCount",
                  "value": 1
                },
                "runAfter": {
                  "Capture_error": ["Succeeded"]
                }
              },
              "Check_if_should_retry": {
                "type": "If",
                "expression": {
                  "less": ["@variables('retryCount')", 3]
                },
                "actions": {
                  "Wait_before_retry": {
                    "type": "Wait",
                    "inputs": {
                      "interval": {
                        "count": 30,
                        "unit": "Second"
                      }
                    },
                    "runAfter": {}
                  }
                },
                "else": {
                  "actions": {}
                },
                "runAfter": {
                  "Increment_retry": ["Succeeded"]
                }
              }
            },
            "runAfter": {
              "Try_operation": ["Failed", "TimedOut"]
            }
          }
        },
        "runAfter": {
          "Initialize_last_error": ["Succeeded"]
        },
        "limit": {
          "count": 10,
          "timeout": "PT1H"
        }
      },
      "Check_final_result": {
        "type": "If",
        "expression": {
          "equals": ["@variables('succeeded')", false]
        },
        "actions": {
          "Log_to_dead_letter": {
            "type": "OpenApiConnection",
            "inputs": {
              "host": {
                "apiId": "/providers/Microsoft.PowerApps/apis/shared_sharepointonline",
                "connectionName": "shared_sharepointonline",
                "operationId": "PostItem"
              },
              "parameters": {
                "dataset": "@parameters('deadLetterListUrl')",
                "table": "DeadLetterQueue"
              },
              "body": {
                "Title": "@{triggerBody()?['operationName']} - Failed",
                "CorrelationId": "@{coalesce(triggerBody()?['correlationId'], guid())}",
                "Payload": "@{string(triggerBody()?['payload'])}",
                "ErrorMessage": "@{variables('lastError')}",
                "RetryCount": "@{variables('retryCount')}",
                "FailedAt": "@{utcNow()}"
              }
            },
            "runAfter": {}
          },
          "Send_failure_alert": {
            "type": "OpenApiConnection",
            "inputs": {
              "host": {
                "apiId": "/providers/Microsoft.PowerApps/apis/shared_office365",
                "connectionName": "shared_office365",
                "operationId": "SendEmailV2"
              },
              "parameters": {
                "emailMessage/To": "@parameters('adminEmail')",
                "emailMessage/Subject": "[ALERT] Flow Failed: @{parameters('flowName')}",
                "emailMessage/Body": "<h2>Flow Execution Failed</h2><p><b>Flow:</b> @{parameters('flowName')}</p><p><b>Operation:</b> @{triggerBody()?['operationName']}</p><p><b>Error:</b> @{variables('lastError')}</p><p><b>Retry Attempts:</b> @{variables('retryCount')}</p><p><b>Correlation ID:</b> @{coalesce(triggerBody()?['correlationId'], 'N/A')}</p><p><b>Time:</b> @{utcNow()}</p><hr/><p>The payload has been logged to the dead letter queue for manual review.</p>",
                "emailMessage/Importance": "High",
                "emailMessage/IsHtml": true
              }
            },
            "runAfter": {
              "Log_to_dead_letter": ["Succeeded", "Failed"]
            }
          },
          "Respond_with_failure": {
            "type": "Response",
            "kind": "Http",
            "inputs": {
              "statusCode": 500,
              "body": {
                "success": false,
                "error": "@{variables('lastError')}",
                "retries": "@{variables('retryCount')}",
                "correlationId": "@{coalesce(triggerBody()?['correlationId'], guid())}"
              }
            },
            "runAfter": {
              "Send_failure_alert": ["Succeeded", "Failed"]
            }
          }
        },
        "else": {
          "actions": {
            "Respond_with_success": {
              "type": "Response",
              "kind": "Http",
              "inputs": {
                "statusCode": 200,
                "body": {
                  "success": true,
                  "retries": "@{variables('retryCount')}",
                  "correlationId": "@{coalesce(triggerBody()?['correlationId'], guid())}"
                }
              },
              "runAfter": {}
            }
          }
        },
        "runAfter": {
          "Retry_loop": ["Succeeded", "Failed", "TimedOut"]
        },
        "description": "Handle final success or failure after retries exhausted"
      }
    }
  }
}
