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

2

5

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.

Offwhite answered 13/8, 2019 at 19:21 Comment(0)
S
6

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.

Steak answered 14/8, 2019 at 9:49 Comment(2)
It took me a while to be able to test it. I rolled back to the original answer as setting the header is a useful addition as well as the status code.Offwhite
Glad to see that.Steak
P
3

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.

Platitudinize answered 14/12, 2023 at 18:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.