Why does extract variables remove backslash characters from a properly escaped JSON property value?

I'm using Extract Variables (EV) to get a "systemMessage" from a backend error response that may contain properly escaped quote chars. EV populates the variable but drops the backslashes.

Then, when I use a subsequent Assign Message (AM) policy to set that value in my standard error response message, the quote chars are not escaped and message is not valid JSON.

Here's my backend response:

{
      "code": "INVALID",
      "user_message": "Invalid value for \"logonId\" check your input."
}

Here's the EV policy:

<ExtractVariables name="EV-BackendErrorResponse">
    <DisplayName>EV-BackendErrorResponse</DisplayName>
    <JSONPayload>
        <Variable name="standard.systemMessage">
            <JSONPath>$.user_message</JSONPath>
        </Variable>
    </JSONPayload>
</ExtractVariables>

Here's the AM policy in DefaultFaultRule:

<AssignMessage name="AM-SetStandardFaultResponse">
    <DisplayName>AM-SetStandardFaultResponse</DisplayName>
    <Set>
        <Payload contentType="application/json">
           {
              "code": "{standard.errorCode}",
              "userMessage": "{standard.userMessage}",
              "systemMessage": "{standard.systemMessage}",
              "info": "http://company.com/docs/errors#{standard.errorCode}"
           }
        </Payload>
        <StatusCode>{standard.errorStatusCode}</StatusCode>
        <ReasonPhrase>{standard.errorReasonPhrase}</ReasonPhrase>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

Here's the invalid result:

{
      "code": "proxyname.409.001",
      "userMessage": "Invalid credentials",
      "systemMessage": "Invalid value for "logonId" check your input.",
      "info": "http://developer.company.com/docs/errors#proxyname.409.001"
}

Why can't EV just leave well enough alone?

Probably have to use JS callout to process the response and ensure properly escaped values.

1 6 1,551
6 REPLIES 6

OK, a simple JS callout does the trick.

var content = context.getVariable('response.content');
var response = JSON.parse(content);
var str = JSON.stringify(response.user_message);
// Drop the leading and trailing quotes
context.setVariable('standard.systemMessage', str.substring(1,str.length-1));

Seems like a bug.

I don't think it's a bug. I think the behavior you're seeing is just a side effect of the JSON serialization.

To avoid it, you can do this:

<AssignMessage name="AM-SetStandardFaultResponse">
    <DisplayName>AM-SetStandardFaultResponse</DisplayName>
    <Set>
        <Payload contentType="application/json">
           {
              "code": "{standard.errorCode}",
              "userMessage": "{escapeJSON(standard.userMessage)}",
              "systemMessage": "{escapeJSON(standard.systemMessage)}",
              "info": "http://company.com/docs/errors#{standard.errorCode}"
           }
        </Payload>
        <StatusCode>{standard.errorStatusCode}</StatusCode>
        <ReasonPhrase>{standard.errorReasonPhrase}</ReasonPhrase>
    </Set>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
    <AssignTo createNew="false" transport="http" type="response"/>
</AssignMessage>

That AssignMessage shows the use of a helper function called escapeJSON. You can wrap that around a variable reference inside the message template, and it will escape the double-quotes in the value stored in the variable.

Try and see!

Awesome, that works!

Um, uh, where is that documented? What other functions are available?

Confound it! I don't see that documented ANYWHERE.

there are 4 functions available:

  • escapeJSON
  • escapeXML
  • toUpperCase
  • toLowerCase

They each accept a single variable as an argument.

Case matters. (eg, don't use EscapeJson)

@Floyd Jones you probably aren't doing anything now, right?

See also APIRT-3489 . @docs

Thanks @Dino, for a splendid answer as always.

There are more than 4 functions available now. https://docs.apigee.com/api-platform/reference/message-template-intro#using-message-template-functio...

Yes, we've added new functions to that list.