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
:HttpError
stringmessage
: 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:
assign
call
for
parallel
raise
return
steps
switch
try
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.