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).
Sergii Melnykov
Participating Frequently
January 29, 2025

Sergii, I appreciate you're likely hoping to hear from anyone who "knows the answer" to your challenge. Maybe someone will, but until then perhaps the following will help us help you. 

 

1) Have you tried simply using cfheader and cfcontent instead? I ask because by dropping to the lower level of Tomcat (the servlet context, via that cfml  getpagecontext function), you may be getting or losing something as compared to the purely cfml approach. It's worth a try--and it requires no mods to cf or iis or your application.cfc (more on that in a moment) 

 

2) Also, is this code being done in a method of a cfc? If so, what's the method's returntype and returnformat? Are you setting one or leaving it as the default? And is this cfc being called directly via http? That has its own impact on how content is returned. 

 

3) You've also not clarified what web server you're using. You mentioned iis. That could be configured in a way that's impacting thus behavior, especially non-200 status codes.

 

It could be interesting to hear if the result would be different if you called such a page via cf's builtin web server, which is how folks access the cf admin, by default at port 8500 (to run code in the cfusion/wwwroot folder). 

 

4) to that last point, have you tried things in other than the one environment you're referring to? Do you have a test environment? A free development environment? Even if that wouldn't work for your entire app, at least you could test small samples which would help you know where the issue may be, if it happens one place or way but not another. 

 

5) It may help us to know what Cf version you're running. 

 

6) Finally, back to the discussion of application.cfc, why is it off-limits for you to modify that? Is it that you don't want to affect other templates in that same folder or its subfolders? Couldn't you put this sort of code in its own folder with its own application.cfc? that could even be coded to leverage things in the parent's app? The reason that "can't work" for you may well be clear to you and would make sense if you relayed it, but I wanted to ask. Again, it may not even be necessary for this challenge.

 

Hope that's helpful. 


Thank you for your prompt answer Charlie!

It's hard to structure by thse points exactly, but I'll try:

1) Yes, no luck. Tried by rebuilding from the inside and just by making a super bare-bones sample with just cfheader and cfcontent - all the same.

2) CFC, but it's called indirectly. I structured my part of the application similar to a typical fw/1 app, except that I don't have Application.cfc or the framework itself, but some of it's functions (including shortcutting to JSON output skipping a layout) are replicated by other CFCs.

3) It's mostly stock CF and stock stub pages identical to what Martie has originally reported on this topic.

4) Sure, I tried on Lucee local env and it doesn't have any issues whatsoever. 

5) It's CF2021 on the target environment

6) Business reasons. They don't want relative outsiders crash anything outside of the job scope. I agree, that would have put a lot of additional strain on their QA.

If I could have my own Application.cfc etc, I'd just drop in a framework that handles all of it, but currently I can't. My goal is to modernize it from the inside without touching any of the older parts.

 

Hope it explains it. I know that it's weird.