Welcome Guest, Not a member yet? Register   Sign In
Throw Exception From AJAX Call
#1

[eluser]craigkoster[/eluser]
My application does quite a bit of AJAX calls to controllers like such:
Code:
$.ajax(
{
    type : 'POST',
    url : '/ajax/create_account/',
    dataType : 'json',
    data : $('form').serializeArray(),
    success : function (data)
    {
        //show success message
    },
    error : function(xhr, ajaxOptions, thrownError)
    {
        //show error message
    }
)

On the controller side, I'd like to be able to do the following:
Code:
function create_account()
{
    try
    {
         if(failure_condition())
        {
             throw new Exception('There was a problem.');
        }
    }
    catch(Exception $ex)
    {
        throw $ex;
    }

}

When I throw an exception this way jQuery behaves as I would expect and executes the error: handling function but it seems like I can't get a nice clean message from the PHP Exception object. The message is there but it's all formatted with all kinds of other HTML that I have no need for - I just want the message (e.g. 'There was a problem') so I can display it formatted to my liking.

Is there no way to get just the simple message from an Exception object with none of the formatting? This seems pretty odd to me.

Thanks for any insight you can give.

Craig

P.S. - I know someone will ask why I'm using exceptions to send messages - it's because I'd rather not have to have conditional checks in all my jQuery success: handlers to see if the executed AJAX call had any errors in it.
#2

[eluser]craigkoster[/eluser]
OK...figured out part of the problem is that I have xdebug running which takes all error messages and formats them nicely via HTML. I removed the xdebug module but my calls to $ex->getMessage() still returns:

Fatal error: Uncaught exception 'Exception' with message 'this is a test' in /[path]:28 Stack trace: #0 [internal function]: Ajax->create_account() #1 /[path]CodeIgniter.php(232): call_user_func_array(Array, Array) #2 /[path]index.php(115): require_once('/[path]) #3 {main} thrown in /[path]/ajax.php on line 28

Is there no way to just get the 'this is a test' part of the message?
#3

[eluser]BrianDHall[/eluser]
http://us.php.net/manual/en/language.exceptions.php

According to this getMessage() SHOULD return only the message you have set - but you are getting an uncaught exception error, which is because inside your catch block you are throwing $ex again.

PHP cannot pass the exception as an object to your AJAX browser simply by throwing it. By throwing it you are making PHP ask, "OK, then what do I do with it?" With no catching in PHP it triggers the uncaught exception error.

Instead of throwing the error, you need to return something to your AJAX in string form, such as your getMessage() string, and your AJAX needs to determine if there was an error some other way and then proceed from there. You could for instance check the returned string for "[ERROR]", and in your PHP catch block make the value echo'ed out to return to your AJAX function be "[ERROR]{$ex->getMessage()}".
#4

[eluser]craigkoster[/eluser]
Thanks for the info, Brian. I suspected that was the case. I was previously just returning JSON with a success flag which I was checking in my AJAX call (e.g. if success then do this otherwise show nice error). I thought that maybe it'd be cleaner to use exceptions but it looks like I'll have to just switch my catch{} blocks to take the exception and format ->getMessage() to JSON in order to return it to my AJAX call.

Thanks again for the info.

Craig
#5

[eluser]attos[/eluser]
What I do is to use jQuery's to display either success or error messages.

The requesting page the Ajax call is:
Code:
$.ajax(
  { url: '<?php echo base_url().'ajax/create_account/'?>'
  , type: 'post'
  , dataType: 'text'
  , data: $('form').serializeArray()
  , success: function (data) { $('#message_div').html(data.responseText).removeClass().addClass(success_class).show(); }
  , error: function (data) { $('#message_div').html(data.responseText).removeClass().addClass(error_class).show(); }
});

Please note that I'm using a text response since I'm only displaying the message and not processing anything from the server. I would use the json or xml dataType if any data needs to be processed. (BTW I like the commas in front of multi-line statements. It is easier for me to add and delete lines and not worry about the last line that does not end with a comma :-))

In the controller:
Code:
try
{
  $this->your_model->create_account();
  $data = 'Your accouont has been created';
  $this->load->view('ajax_text_view', array('data'=>$data));
}
catch (AppException $ex)
{
  $message = 'An error occurred while processing the request: '.$message;
  $this->output->set_status_header('500');
  $this->load->view('ajax_text_view', array('data'=>$message));
}

I'm assuming you're using a model to create the account, which throws an exception in case of an error. Please note that when catching an exception the response status header is set to 500 (http error). This causes to execute the error function in jQuery.

Finally a view sets the http header and the content:
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
  header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
  header("Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT");
  header("Cache-Control: no-cache, must-revalidate");
  header("Pragma: no-cache");
  header("Content-type: text/plain");
  echo $data;

There are also two CSS class for success_class (green background with a check-mark image) and for the error_class (red background and a stop sign image).




Theme © iAndrew 2016 - Forum software by © MyBB