When a workflow throws an error during execution, it can be caught and handled.
Use a try/except structure
You can use a try/except structure for error handling. For example:
YAML
- STEP_NAME: try: call: http.get ... except: as: ERROR_MAP steps: ...
JSON
[ { "STEP_NAME": { "try": { "call": "http.get" ... }, "except": { "as": "ERROR_MAP", "steps": ... } } } ]
Replace ERROR_MAP with the name of a map variable that
contains the error message.
For example, the map for an HttpError error (with an HTTP status code >= 400)
has the following attributes:
tags:HttpErrorstringmessage: human-readable error messagecode: HTTP status codeheaders: response headersbody: response body
For other error tags, see Workflow errors.
Note that the steps block is optional. It can contain the following:
Variable scope
A variable created inside an except block belongs to the local scope of that
block, and is accessible only in that scope. For details, see
Variables.
If you are assigning a variable inside an except block and want to access the
variable outside of the block, assign the variable before the block to place
it in the surrounding scope. For details, see
Share a variable before an except block.
Example of try/except structure
For example, Workflows considers any HTTP request that returns
status code 400 or greater failed. This makes the workflow execution fail
unless the workflow catches and handles the error:
YAML
- read_item: try: call: http.get args: url: https://host.com/api result: api_response except: as: e steps: - known_errors: switch: - condition: ${not("HttpError" in e.tags)} return: "Connection problem." - condition: ${e.code == 404} return: "Sorry, URL wasn't found." - condition: ${e.code == 403} return: "Authentication error." - unhandled_exception: raise: ${e} - url_found: return: ${api_response.body}
JSON
[ { "read_item": { "try": { "call": "http.get", "args": { "url": "https://host.com/api" }, "result": "api_response" }, "except": { "as": "e", "steps": [ { "known_errors": { "switch": [ { "condition": "${not(\"HttpError\" in e.tags)}", "return": "Connection problem." }, { "condition": "${e.code == 404}", "return": "Sorry, URL wasn't found." }, { "condition": "${e.code == 403}", "return": "Authentication error." } ] } }, { "unhandled_exception": { "raise": "${e}" } } ] } } }, { "url_found": { "return": "${api_response.body}" } } ]
The try block can contain multiple steps, allowing them to share the same
except block for error handling:
YAML
- read_item: try: steps: - step_a: call: http.get args: url: https://host.com/api result: api_response1 - step_b: call: http.get args: url: https://host.com/api2 result: api_response2 ... except: as: e steps: - KnownErrors: ...
JSON
[ { "read_item": { "try": { "steps": [ { "step_a": { "call": "http.get", "args": { "url": "https://host.com/api" }, "result": "api_response1" } }, { "step_b": { "call": "http.get", "args": { "url": "https://host.com/api2" }, "result": "api_response2" ... } } ] }, "except": { "as": "e", "steps": [ { "KnownErrors": null } ... ] } } } ]
Use a try/retry/except structure
You can also use a try/retry/except structure for error handling. For example:
YAML
- step_name: try: steps: - step_a: call: http.get args: url: https://httpstat.us/404 retry: ${http.default_retry_non_idempotent} except: as: e steps: - checkForTimeout: switch: - condition: ${e.code == 404} return: "notfound_404" - condition: ${e.code == 408} return: "timeout_408" - raiseError: raise: ${e} - returnSuccess: return: "Success"
JSON
[ { "step_name": { "try": { "steps": [ { "step_a": { "call": "http.get", "args": { "url": "https://httpstat.us/404" } } } ] }, "retry": "${http.default_retry_non_idempotent}", "except": { "as": "e", "steps": [ { "checkForTimeout": { "switch": [ { "condition": "${e.code == 404}", "return": "notfound_404" }, { "condition": "${e.code == 408}", "return": "timeout_408" } ] } }, { "raiseError": { "raise": "${e}" } } ] } } }, { "returnSuccess": { "return": "Success" } } ]
For more information, see Retry steps.
Catch and handle HTTP request errors
This sample implements a custom exception handler based on the HTTP status code returned by the GET request. The workflow catches a potential exception and returns a predefined error message. If an exception is not recognized, the workflow execution fails and throws the exception as returned by the GET request.
The same pattern could be used to catch exceptions raised by Cloud Run or Cloud Run functions workloads.