Skip to main content
Inspiring
September 17, 2019
Answered

restSetResponse content

  • September 17, 2019
  • 1 reply
  • 2412 views

Well, this is an extremely frustrating function. Especially for produces="application/json"

Depending on what you set the status to, your content is overridden by messages or default templates.

A few test functions:


status 401, 404 return body with html default template instead of specified content

 

 

//test function for 404 - returns html default template
remote void function notfound()
	httpmethod="GET"
	restpath="/not-found"
{
	response = {
		content: "Oops, not found",
		status: 404
	};
	restSetResponse(response);					
}

 

 


status 422 returns body with html "The custom error module does not recognize this error."

 

 

//test function for 422 - returns "The custom error module does not recognize this error."
remote void function UnprocessableEntity()
	httpmethod="GET"
	restpath="/unprocessable-entity"
{
	response = {
		content: "Oops, unprocessable entity",
		status: 422
	};
	restSetResponse(response);					
}

 

 

 
The purpose of having produces="application/json" was to always have the body/content a JSON structure -
which obviously isn't going to happen if my content is ignored. For example -

 

 

//json structure for errors
private Struct function handlerError( required string funcName, required any e)
{
	var funcResp	    = structNew();
        funcResp.error	    = true;
        funcResp.msg	    = ARGUMENTS.e.message;
        funcResp.type	    = ARGUMENTS.funcName & " -> " & ARGUMENTS.e.type;
        funcResp.error_code = ARGUMENTS.e.errorCode;

        return SerializedJSON(funcResp);
}

// should return for 422
{"error":true,"msg":"Oops, unprocessable entity","type":"Unprocessible Entity","error_code":"422"}
// should return for 404
{"error":true,"msg":"Oops, not found","type":"Not Found","error_code":"404"}

 

 


How can I override the override, so my content is returned in the body?
Environment: Windows Server 2012R2 v6.2, CF2016, IIS v8

 

Correct answer BKBK

When you serialize to JSON you essentially get a string. But, here, your function is returning a struct instead. 

So, you should modify the code to something like

 

private String function handlerError( required string funcName, required any e)
{
	var funcResp	    = structNew();
        funcResp.error	    = true;
        funcResp.msg	    = ARGUMENTS.e.message;
        funcResp.type	    = ARGUMENTS.funcName & " -> " & ARGUMENTS.e.type;
        funcResp.error_code = ARGUMENTS.e.errorCode;

        return serializeJson(funcResp);
}

  

1 reply

BKBK
Community Expert
BKBKCommunity ExpertCorrect answer
Community Expert
October 5, 2019

When you serialize to JSON you essentially get a string. But, here, your function is returning a struct instead. 

So, you should modify the code to something like

 

private String function handlerError( required string funcName, required any e)
{
	var funcResp	    = structNew();
        funcResp.error	    = true;
        funcResp.msg	    = ARGUMENTS.e.message;
        funcResp.type	    = ARGUMENTS.funcName & " -> " & ARGUMENTS.e.type;
        funcResp.error_code = ARGUMENTS.e.errorCode;

        return serializeJson(funcResp);
}

  

Sergii Melnykov
Participating Frequently
January 29, 2025

Hello,

This seems relevant as I'm trying to add some AJAX to an existing application, but I ran into the same general issue.

Can I have the same JSON handling when output is done with the following approach?

 

 

getPageContext().getResponse().setStatus(422);
getPageContext().getResponse().setContentType('application/json; charset=utf-8');
writeOutput(serializeJson(data));

 

As implemented above all of the 4xx errors are replaced with corresponding HTML stubs, while code 200 works perfectly. I can have a workaround with the status code in the body, but I wanted to keep it semantical on JS error handler side.
My situation is complicated a little bit by no control over CF settings either directly or via the Application.cfc (and IIS likewise).
Charlie Arehart
Community Expert
Community Expert
January 30, 2025

Hmm, my previous answer seems to be lost.

So 422 is just an example as QA wanted to the whole range of typical status codes supported, from 400 to 422 (situation vary: missing attributes, wrong attribute ranges, wrong methods, missing endpoints, session time out, missing access rights for the entity, some processed DB failures). In my case it doesn't really matter as all of them got intercepted and only the body differs: 400 might be just a plain text status description and 404/405 are full html pages.


Since you're not using the cf rest framework, I'd say the behavior to expect from that Cf function is undefined. But then you said earlier that your attempt to use cfheader and cfcontent didn't work. It seems like something is potentially interfering. 

 

So I'll go back to my earlier point that you never addressed: create a local cf development environment and try things there. And in your bare bones example, put it in a folder with an empty application.cfc, to keep any code in another or the parent folders from causing unexpected impact.

 

And test it both with the cf builtin web server, and with whatever real web server you use (iis?), to see if those differ. I don't think this is an insurmountable problem: it's just a challenging one and we're giving you ideas to pursue. (and I'm always writing from a phone when I see these, so I'm not testing things myself. Perhaps bkbk will.) 

/Charlie (troubleshooter, carehart. org)