opticyclic
opticyclic

Reputation: 8116

How Do I Throw An Error In Azure API Management Policy?

In my Azure API Management Policy I am checking for some headers and do certain actions depending on what is found.

How do I throw an error when none of the conditions are matched (i.e. in the otherwise block)

<policies>
  <inbound>
    <choose>
      <when condition="">

      </when>
      <when condition="">

      </when>
      <otherwise>

      </otherwise>
    </choose>
    <base/>
  </inbound>

  <backend>
    <base/>
  </backend>
  <outbound>
    <base/>
  </outbound>
  <on-error>
    <base/>
  </on-error>
</policies>

I probably want to return a 401 since I am checking groups in the headers.

Upvotes: 5

Views: 5353

Answers (2)

Alex J
Alex J

Reputation: 10205

The accepted solution has the downside of having to build the response from scratch. This makes it difficult if you want to standardize your error responses. I've found that the following hack works well enough:

<set-variable name="Error" value="@{ throw new Exception("400:ERR_001"); }" />

This drops you into on-error, with an ExpressionValueEvaluationFailure. You can then parse out the error code/status:

<choose>
    <when condition="@(context.LastError.Reason == "ExpressionValueEvaluationFailure" && string.IsNullOrEmpty(context.Variables.GetValueOrDefault<string>("ErrorCode")))">
        <set-variable name="ErrorCode" value="@{
            var match = Regex.Match(context.LastError.Message, @"^Expression evaluation failed\. (?:(\d{3}):)?(\w+_\d{3})$");
            return match.Success ? match.Groups[2].Value : null;
        }" />
            
        <choose>
            <when condition="@(!string.IsNullOrEmpty(context.Variables.GetValueOrDefault<string>("ErrorCode")))">
                <set-status code="@{
                    var match = Regex.Match(context.LastError.Message, @"^Expression evaluation failed\. (?:(\d{3}):)?(\w+_\d{3})$");
                    return match.Success ? int.Parse(match.Groups[1].Value) : 500;
                }" />
            </when>
        </choose>
    </when>
</choose>

You can then use the ErrorCode variable in your error response.

Upvotes: 3

Joey Cai
Joey Cai

Reputation: 20067

You can use a <choose> policy to detect and report failure, return a 401 response.

<otherwise>
    <return-response >
        <set-status code="401" reason="Unauthorized" />
        <set-header name="WWW-Authenticate" exists-action="override">
            <value>Bearer error="invalid_token"</value>
        </set-header>
    </return-response>
</otherwise>

Here is also a similar SO thread you could refer to.

Upvotes: 6

Related Questions