views:

760

answers:

6

Hi,

I'm using the Kohana PHP Framework for an application. Now I'm running into a problem, when jQuery does an AJAX request to a certain file, it does work, but when this file throws an PHP exception, jQuery fails and doesn't show the output of the file.

A little example, this is the piece of Javascript:

$.post($('#' + e.currentTarget.id).attr('action'), $('#' + e.currentTarget.id).serialize(), function ( data )
{
    alert ( data );
}/*, 'json' */);

Now this works when the PHP file does this (the alert box pops up):

<?php echo 'Test'; ?>

But when somewhere in the PHP file this happens:

<?php throw new Exception ( 'Test' ); ?>

jQuery fails and doesn't show the outputted HTML error, also there is a difference in PHP headers (generated by PHP?):

With the PHP echo (good):

. Connection:Keep-Alive
. Content-Encoding:gzip
. Content-Length:544
. Content-Type:text/html; charset=UTF-8
. Date:Wed, 22 Jul 2009 14:22:43 GMT
. Keep-Alive:timeout=15, max=100
. Server:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
. Vary:Accept-Encoding
. X-Powered-By:PHP/5.2.6

With the PHP exception (fail):

. Connection:close
. Content-Encoding:gzip
. Content-Length:1896
. Content-Type:text/html; charset=UTF-8
. Date:Wed, 22 Jul 2009 14:23:11 GMT
. Server:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
. Vary:Accept-Encoding
. X-Powered-By:PHP/5.2.6

Now I don't really see a problem, both ways PHP echoes some HTML. Somebody had this problem before, and how'd you fix this?

Thanks for the help!

+2  A: 

If you want to keep your current error reporting level, but still give a nice error message to jQuery you can wrap your code in a try-catch block.

try {
  // your code
} catch(Exception $e) {
  echo $e->getMessage();  // formatted nicely or a generic message or something.
}
Brian Ramsay
I assume Kohana does it that way, when an exception occurs, Kohana will return the whole backtrace as error message (HTML). Only the headers differ.
Stefan
Though if you do it yourself, it might not bubble all the way to the top and cause Kohana to change the headers? Just tossing that out there.
Brian Ramsay
A: 

+1 with Brian. If you want to know the cause, here it is: jQuery is expecting to receive JSON data. When PHP outputs its error, it outputs HTML and plain text not enclosed within quotes, and this is not valid JSON, so jQuery fails.

If you comment out the 'json' parameter, then if nothing happens, it's because your server sent a statut code representig an error (any statut code > 500). If you could provide us this information, that would be good.

FWH
But when JSON is commented out (as in my example and live version), it would just display the whole HTML output?
Stefan
It should, unless your server sends a statut code 500.
FWH
+2  A: 

To show what the error is, you can do this in your ajax call.

jQuery.ajax({
 type: "POST",
 ...
 error: function(xhr, desc, e) {
    alert(xhr.responseText);
   }
});

This should alert you with the same html that throwing a PHP exception would give you on a regular page.

Michal Gorecki
This work, anyone else having this problem, see the code I posted below, thanks!
Stefan
A: 

I would encourage you to try out the Firebug addon for Firefox. Firebug will easily allow you to look at the AJAX request and see what data is being returned by your application.

pifantastic
I'll look that one up sometime when having new problems, Firefox is slow stuff on Mac, too bad for some handy plugins
Stefan
A: 

As a few people have already guessed, Kohana's default exception handler sets the HTTP response status to "500 Internal Server Error". If you want to return errors to your JavaScript you'll need to catch the exceptions and output error messages manually.

D. Evans
That was the problem afterall, yes
Stefan
A: 

Solution thanks to goreckm:

$.ajax({
    type    : 'POST',
    url     : $('#' + e.currentTarget.id).attr('action'), // http://www....
    dataType: 'json',
    data    : $('#' + e.currentTarget.id).serialize(), // Data to be sent
    success : function ( data )
    {
     alert ( data );
    },
    error   : function ( ajax_response )
    {
     alert ( ajax_response.responseText );
    }
});
Stefan