Exception handling for Logic Apps web services

This post was originally published here.

This blog post covers some aspects about exception handling in case you expose nested workflows as a web service. When dealing with web services, it’s important to ensure that no time outs are triggered and that meaningful exception messages are returned to the client. Let’s have a look how this can be done.


As a starting point, I create Logic App 1 that is exposed as a web service and which invokes Logic App 2 in a synchronous way. The second Logic App just puts a request on a Service Bus queue. Once that action is completed, a response is returned and the first Logic App can return a success to the consuming application.

Configure retry policy

Because I want to avoid timeouts because of automatic retries, I update the Call Logic App 2 action, so it will not perform a retry. This is done in the code view. Depending on your use case, you could also limit the number of retries. The minimal time interval between retries is 20 seconds, which is also the default value. This is quite high for a web service scenario, as most clients time out after 60 seconds.

Run an exception scenario

To see what happens in case of an exception, I reconfigure Logic App 2 to send to a non-existing queue. In both Logic Apps, the Response action is skipped because the Logic App stops processing in case of a failure.

The web service call results in a meaningless exception message for the consuming application:

Optimize for exceptions

Ensure a meaningful exception is returned

Let’s first change the Logic App 2, so it returns the real Service Bus exception in case of a failure. The recommended way, is to add a Scope around the Send Message action. The details of the scope outcome are provided via the @result function. More information is given here. Depending on the resulting outcome of the scope, a different response can be returned.

Remark the Switch statement, based on the status of the scope.  The @result function returns an array, that provides a result for each action within the scope.   The status of the first action is extracted via this expression: @result(‘scope’)[0][‘status’].
In the Failure Response, I return the resulting status code – @result(‘scope’)[0][‘outputs’][‘statusCode’] – and exception message – @result(‘scope’)[0][‘outputs’][‘body’][‘message’].

Changing Logic App 1 to meet the expectations is a lot easier.  Just ensure it returns the status code and message from the invoked Logic App.

Ensure the Logic App continues on failure

Another optimization we must perform, is to configure the Response action and Switchstatement to also run in case the preceding action fails. This can be done within the code view:

Inspect the result

Exception scenario

If we trigger an exception scenario, the run detail of Logic App 2 looks good. The Scopehas failed, which is detected by the Switch statement and the Logic App returns the Failure Response.

The outcome of Logic App 1 also meets the expectations, as the response of Logic App 2 is returned to the consuming client.

The web service client also gets a nice exception message.

Sucess scenario

We completely focused on the exception scenario, so it’s good to double check that the happy path still behaves well. Just update Logic App 2, to send now to an existing queue. Logic App 2 sends a success response, which is great!

Logic App 1 shows only green statuses:

The web service client gets a confirmation that the message got queued!


The default settings for retry policies and exception handling might not always fit your scenario. Make sure you understand the Logic Apps capabilities on this matter and apply them according to your needs. Small prototyping exercises can serve as basis for development guidelines and best practices.

Happy exception handling!



Your Azure Coach is specialized in organizing Azure trainings that are infused with real-life experience. All our coaches are active consultants, who are very passionate and who love to share their Azure expertise with you.