Symfony v2.8 Response( $message ) method 'returning' more than expected
Asked Answered
M

2

7

My goal is to return a message to my web-page, where it is to be displayed, but instead of just the message, the value returned contains the message and html code for an error page!

Here is the Symfony bundle action routing and function definition:

/**
 * @Route("/Utilities/getMessages/{callSign}/{loginDateTime}",
 *        defaults={"callSign"="","loginDateTime"=""})
 *
 * @return:     json string.
 *
 */

public function getMessagesAction( $callSign, $loginDateTime ) { ... }

I am using the following code to return a message result to an ajax call:

Server-Side PHP code that is called by an Ajax call ...

$message = 'Some message to be displayed.';

// Return to the page and display the message ...

return new Response( $message );  // Inspecting $message shows only
                                  // 'Some message to be displayed.'

Client-Side JavaScript code that calls the above code and receives the response:

$.ajax( { // Send form data to the same page that the page came from
          type:        'POST',
          data:        data,
          cache:       false,
          async:       true,
          contentType: false,
          enctype:     'multipart/form-data',
          processData: false
        } )
.done( function( data, textStatus, jqXHR ) { ... } // Inspecting data
                                                    // shows more than
                                                    // 'Some ...
.fail( function( jqXHR, textStatus, errorThrown ) { ... }

When breakpoints are set at the return new Response( $message ); and first executable line in the .done(...) function, the PHP script execution gets to the breakpoint at the return new Response( $message ); statement without any errors and I can see that the parameter's value is 'Some message to be displayed.', as expected, but when paused at the .done() function's first line, the data parameter's value is: Some message to be 'displayed.<!DOCTYPE html><html>...</html>!

Where, if the html code is placed in a file and loaded into the browser it looks somewhat like this:

Whoops, looks like something went wrong.
1/1 FatalErrorException in debug-eval(1) : eval()'d code line 1:
Parse Error: syntax error, unexpected ')'
in debug-eval(1) : eval()'d code line 1

An obvious error message, but my code isn't using any eval() statements that could fail and the execution got to the Response statement without any errors. Is this a bug in the Symfony Response statement method/function? If not, how can I find out what is really happening, so I can fix it?

Follow-Up

Changing the server-side code to encode a json string and then decoding it on the client-side doesn't help.

Server-Side PHP code:

// Return to the login page and display the message ...

// $message'value => '{ "message":"' . $message . '"}';

$message = json_encode( [ 'message' => $message ] ); 
return new Response( $message );

Client-Side Javascript:

    ***unchaged***

In this case I'm still inspecting the data parameter, but it now now contain the json encoded message AND the html error page code. Feeding this to the JSON.parse( data ); statement to convert the json data to an javaScript object causes the javaScript to freeze. This isn't a json issue, the problem of the html code appended to the end of my message still is happening either way.

Thank you

Mannos answered 14/3, 2021 at 3:5 Comment(4)
This is not a fix, but a work around, The problem doesn't manifest itself until the response is passed back to the .done function, where you must remove the html page that is appended to the end of the message or the json string, and then process the message values normally. Too bad that this has to be done on the client-side in JavaScript. My PHP script sets the $message variable to different values, and most of them come out in JavaScript just fine, except a few that include a URL, and these must have the extra HTML code removed before using these values. Hope a future Symfony fixes this.Mannos
Is seems like you have a middleware that is trying to run the eval(). Look for after function in your router. That could affect the Response object between returning it from the controller and the actual generating of the HTTP response.Efferent
Petr Hejda, You're talking about the routing for the bundle action function that receives the ajax posing, right? I updated my question to show the routing.Mannos
I'm running standard Symfony and not aware of any middleware plugins that should interfere with the json return strings.Mannos
G
1

It's not a very clear error message but it sounds like your error is coming from Xdebug, and not PHP.

You can see a similar issue here.

I would check your "Watches" tab in the PHPStorm debug tab, and also from PHPStorm go to Run > View Breakpoints and remove all of them. To be sure you could also deactivate XDebug temporarily (via php.ini settings) to confirm that the problem disappears.

Goody answered 5/4, 2021 at 11:43 Comment(5)
Thank you mickadoo, That makes, sense for the source of the eval message, but it doesn't help much with why the text or json string received as a string is causing the error in the first place.Mannos
What I'm suggesting is that some watch in your IDE might be causing an error and then it's causing the script to stop and output the error you're seeing.Goody
Thanks again. The bounty I offered has expired and I couldn't find a way to just transfer them to you. How do I make good on my offer?Mannos
No worries :-) It helped me find the question and it was interesting to see anyway. Does that mean it solved the issue you were having by removing the watches / breakpoints? If you like you can accept the answer if it solved your question, and then it should be clearer for people in the future who have the same problem.Goody
Your answer seems the most likely cause of the problem, unfortunately, I couldn't actually test it because I have already changed the watches in my debugger. Too bad the browsers don't let you save the watches in a debugging profile so you could easily save and restore them when working on various issues. Anyway, the problem isn't happening at this time, and while I have modified the code a little bit, I didn't change the json and non-json strings that are returned, leaving the watches as the only real changes. Thanks again.Mannos
M
0

Try returning a new JsonResponse($json) instead of new Response($json).

As in:

use Symfony\Component\HttpFoundation\JsonResponse;

// ...
return new JsonResponse(['message' => $message]);

If you really (and I mean really) want to return a Response for whatever reason, you can also do:

$response = new Response(json_encode(['message' => $message]);
$response->headers->set('Content-Type', 'application/json');

return $response;

Bear in mind that I have never tried the last alternative, because JsonResponse has always worked for me. Also, JsonResponse extends Response class, so if you need anything from Response class, you can get it in JsonResponse.

The last response example is attached to this answer because of this Symfony Documentation.

Mariquilla answered 5/4, 2021 at 18:4 Comment(1)
Thank you Rodolfo Rangel, Yes, I do use JsonResponse in other Ajax success returns on the server-side, but in this case, I want to be able to send text strings or JSON strings, depending on what information the Ajax call 'wants', i.e., if a simple text message is needed, then a simple text string is returned; if the form updates the database, then an HTML string is returned; and if data from the database for a specific item is needed, then a json string containing multiple related data values is returned. So, I accept plain old text, and check for surrounding {} characters for json.Mannos

© 2022 - 2024 — McMap. All rights reserved.