Integration attachement error: Response body was requested to be saved as attachment. It's not available through getBody() anymore.

Giovana Lopes
Tera Contributor

Hello,

I have a script wich integrates Azure devops.

When I add attachments from a specific group, it works well, but when I try with another group, the catch script returns: "Response body was requested to be saved as attachment. It's not available through getBody() anymore."

But it doesnt make sense, as well it works with another group.

 

Heres my code:

var att2 = new GlideRecord('sys_attachment');
att2.addQuery('table_sys_id', incident.sys_id);
att2.addQuery('file_name', attchFilename.toString());
att2.query();
if (att2.next()) {
cckFileName2 = true;
} else {
cckFileName2 = false;
}

if((!cckFileName) && (!cckFileName2) && (!comment.contains("Attachment from ServiceNow"))){

//var check = new global.VSTSUtils().getAttachment(attachId, incident.sys_id, Mfilename.toString());
try {
var r = new sn_ws.RESTMessageV2('VSTS Integration BI', 'Get Attachments');
r.setStringParameterNoEscape('id', attachId);
r.saveResponseBodyAsAttachment('incident', incident.sys_id, Mfilename.toString());

var response2 = r.execute();

var responseBody = response2.getBody();

var httpStatus = response2.getStatusCode();

if (httpStatus == "200" || httpStatus == "201") {
}


} catch (ex) {
var message = ex.message;
gs.log('catch: ' + message);
}

 

 

Can anybody help me? 

Thank you

1 ACCEPTED SOLUTION

Rahman3
Tera Expert

Hello,

HTTP response is a stream that you cannot process twice. saveResponseBodyAsAttachment is already processing the response and therefore you cannot do again response.getBody(); 

What you possibly need to do is this:

 

var request = new sn_ws.RESTMessageV2(restName, restMethod);
response = request.execute();
if (response.getStatusCode() == '200') {

var binaryFile = response.getBody();//Receiving excel file, binary data.
var attachment = new GlideSysAttachment();
var sqGr = new GlideRecord(tableName);
sqGr.get(sqTableId);

// Write your own code to save the response Body as attachment

 

Hope this helps

View solution in original post

9 REPLIES 9

Hi,

not much sure on this

Regards
Ankur

Regards,
Ankur
Certified Technical Architect  ||  9x ServiceNow MVP  ||  ServiceNow Community Leader

michaelward
Tera Guru

Yeah, this seems to be buggy as all get out.  When I create a REST service to table_list.do?CSV or table_list.do?EXCEL, it works fine when running a test, but no combination of the following works.  As you can see, the call to the rest service is parameterized as the REST service's Default GET has the proper ?CSV or ?EXCEL extension on the endpoint.  All other combinations seem to not work.  The 'text/html' appears to be that when run via script like below, you just get ServiceNow's html page response, but if you run directly in outbound REST as a test on Default GET method, it works.  Below I was switching between using saveResponseBodyAsAttachment vs. a GlideSystemAttachment.write().  Neither seem to work.  saveResponseBodyAsAttachment gives a stack trace.  GlideSystemAttachment.write() produces corrupted files. By the way, my REST Services are setup with basic auth to a service account and they have a full endpoint.  Partial or relative endpoints, i.e. "/table_list.do?EXCEL' do not work due to a 'host is null' error.

vars passed in:  fileName, tableName, tableId.....

var request = new sn_ws.RESTMessageV2(restName, restMethod);
request.saveResponseBodyAsAttachment(tableName, tableId, fileName);
response = request.execute();
if (response.getStatusCode() == '200') {

var binaryFile = response.getBody();//Receiving excel file, binary data.
var attachment = new GlideSysAttachment();
var sqGr = new GlideRecord(tableName);
sqGr.get(sqTableId);


//attachment.writeBase64(sqGr, fileName, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", gs.base64Encode(binaryFile)); // corruption
//attachment.writeBase64(sqGr, fileName, "text/csv", binaryFile); // corruption
//attachment.write(sqGr, fileName, "text/csv", binaryFile); // this works for .CSV

}

Stack trace:

Security restricted: MIME type mismatch for file: query_attachment3.csv. Expected type:text/csv, Actual type: text/html
Security restricted: File type is not allowed or does not match the content for file query_attachment3.csv
Evaluator: com.glide.rest.util.RESTRuntimeException: Response body was requested to be saved as attachment. It's not available through getBody() anymore. Caused by error in script at line 472 com.glide.rest.outbound.direct.DirectRESTResponse.getBody(DirectRESTResponse.java:86) com.glide.rest.outbound.scriptable.ScriptableRESTResponse.jsFunction_getBody(ScriptableRESTResponse.java:82) sun.reflect.GeneratedMethodAccessor2549.invoke(Unknown Source) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

kente
Tera Guru

Joining in on having the issue.

However i get the actual attachment created, but the REST message still fails with 
"Response body was requested to be saved as attachment. It's not available through getBody() anymore."

Rahman3
Tera Expert

Hello,

HTTP response is a stream that you cannot process twice. saveResponseBodyAsAttachment is already processing the response and therefore you cannot do again response.getBody(); 

What you possibly need to do is this:

 

var request = new sn_ws.RESTMessageV2(restName, restMethod);
response = request.execute();
if (response.getStatusCode() == '200') {

var binaryFile = response.getBody();//Receiving excel file, binary data.
var attachment = new GlideSysAttachment();
var sqGr = new GlideRecord(tableName);
sqGr.get(sqTableId);

// Write your own code to save the response Body as attachment

 

Hope this helps

Hey, Thanks for this. It was very helpful in resolving the error.