6

I'm trying to create an Apex callout and running into the following error message:

System.UnexpectedException: Script-thrown exception

My analysis shows that

  • System.UnexpectedException is not catchable in Apex.
  • There are some reports of exceptions with “Script-thrown exception” message by other users, but the exception type in those cases happen to be System.CalloutException. [1]
  • The only reported case of a System.UnexpectedException with the same message appears to be triggered by log level of Callouts. (Note: the recommended workaround did not solve the problem in our case.) [2]

This is the code that causes the error:

HttpRequest req = new HttpRequest();
req.setEndpoint('callout:AmazonConnectAPI/contact/start-recording');
req.setMethod('POST');
String body = String.format(
  '\'{\'"ContactId": "{0}","InitialContactId": "{1}","InstanceId": "{2}","VoiceRecordingConfiguration": \'{\'"VoiceRecordingTrack": "{3}"\'}\'\'}\'',
  new List<String>{
    contactId,
    initialContactId,
    instanceId,
    voiceRecordingTrack
  }
);
if (body != '') {
  req.setBody(body);
}
Http http = new Http();
HttpResponse resp = http.send(req);

Other notable facts:

  • The HTTP callout is made to a Named Credential called AmazonConnectAPI
  • AmazonConnectAPI is configured for "https://connect.us-east-1.amazonaws.com“
  • The authentication method of the Named Credential is Named Principal with protocol "AWS Signature Version 4"
  • The authentication method uses the credentials for an IAM user with a full-access managed policy to Amazon Connect.
  • The formatting of the body is correct. There is no syntax error.
  • The error comes from this line HttpResponse resp = http.send(req);
3

I was having some issues with my Named Credential (Named Principal) AWS Signature Version 4 and found some resolutions for the below error:

HttpResponse resp = http.send(req);
System.UnexpectedException: Script-thrown exception

1. Named Credential Name

Double check your 'callout:Named_Credential' in Apex matches the Named Credential API 'Name'.

No brainer, but it got me for a few hours.

2. URL Encoded Endpoint

Make sure to escape any URL reserved characters: https://developers.google.com/maps/documentation/urls/url-encoding.

String endpoint = 'callout:Named_Credential/contactId/start=2021-02-10Thh:mm:ss.msm-00:00';

Should probably be:

String endpoint = 'callout:Named_Credential/contactId/start%3D2021-02-10Thh%3Amm%3Ass.msm-00%3A00';

No brainer, but it got me for a few more hours.

3. Escaping Curly Braces in String.format()

I just ran this in Dev Console for your body and got the below:

System.debug((Map<String,Object>) JSON.deserializeUntyped(String.format(
  '\'{\'"ContactId": "{0}","InitialContactId": "{1}","InstanceId": "{2}","VoiceRecordingConfiguration": \'{\'"VoiceRecordingTrack": "{3}"\'}\'\'}\'',
  new List<String>{
    'contactId',
    'initialContactId',
    'instanceId',
    'voiceRecordingTrack'
  }
)));

15:46:47:008 FATAL_ERROR System.JSONException: Unexpected character (''' (code 39)): was expecting comma to separate OBJECT entries at [line:1, column:171]

Changing the last few escaped curly braces from "{3}"\'}\'\'}\'', to "{3}"\'}\'}', got me a correct string

System.debug((Map<String,Object>) JSON.deserializeUntyped(String.format(
  '\'{\'"ContactId": "{0}","InitialContactId": "{1}","InstanceId": "{2}","VoiceRecordingConfiguration": \'{\'"VoiceRecordingTrack": "{3}"\'}\'}',
  new List<String>{
    'contactId',
    'initialContactId',
    'instanceId',
    'voiceRecordingTrack'
  }
)));

15:40:31:006 USER_DEBUG [45]|DEBUG|{ContactId=contactId, InitialContactId=initialContactId, InstanceId=instanceId, VoiceRecordingConfiguration={VoiceRecordingTrack=voiceRecordingTrack}}

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.