views:

70

answers:

2

How can I throw an exception on my server and have the exception's message be read in JavaScript (I'm using AJAX with jQuery). My server environment is Google App Engine (Python).

Here's my server code:

def post(self):
    answer_text = util.escapeText(self.request.get("answer"))
    # Validation
    if ( len(str(answer_text)) < 3):
        raise Exception("Answer text must be at least 2 characters long.")
        return

And here's the AJAX request:

$.ajax({
    type: "POST",
    url: "/store_answer.html",
    data: "question_id=" + question_id +"&answer="+answer,
    success: function(responseText){
    handleSuccessfulAnswer(question_id);
    },
    error: function(responseText){
    // TODO: How to get the exception message here???
    alert("???????????");
    },
    complete: function(data) {
    submitCompleted(submitName, "Submit");
    }
});

Thanks!

+2  A: 

On the server, you need to catch the exception in a try/except block and turn it into a proper HTTP error (with code 500, generic server error, if a server error is what's happened -- 3xx if the problem is with the request, &c -- see here for all the HTTP status codes) with the Response's set_status method.

Alex Martelli
I really want to know how to read the message on the client side... any suggestions how I can do that?
Cuga
@Cuga, see http://stackoverflow.com/questions/377644/jquery-ajax-error-handling-show-custom-exception-messages
Alex Martelli
@Alex: Thanks, that link really helped get the answer I needed.
Cuga
@Cuga, you're welcome!
Alex Martelli
+3  A: 

If you have debug=True in your WSGI app configuration, the stack trace from your exception will get populated to the HTTP response body, and you can parse your message out of the stack trace client side.

Don't do this, though. It's insecure, and a bad design choice. For predictable, recoverable error conditions, you should either be catching the exception or not throwing one at all, e.g.:

if ( len(str(answer_text)) < 3):
    self.error(500)
    self.response.out.write("Answer text must be at least 2 characters long.")
    return
Drew Sears
Would self.response.set_status(500, "Answer text must be...") as suggested by Alex achieve the same thing? Is either approach better?
Saxon Druce
@Saxon The string passed to set_status is the HTTP status string, which won't appear in the body of the response, so it's the wrong place to put error messages.
Nick Johnson
@Nick: Ah I see, thanks. Would it work much the same though if the javascript uses xhr.statusText with the set_status() approach or xhr.responseText with the out.write() approach (these are the top two responses to the question Alex mentioned in his comment - http://stackoverflow.com/questions/377644/jquery-ajax-error-handling-show-custom-exception-messages)? Or is one alternative generally better than the other?
Saxon Druce
I would generally avoid trying to send application-specific messages through the HTTP status - send them in the body, instead.
Nick Johnson
Thanks Nick....
Saxon Druce
Thanks for this discussion, you guys have really helped me learn about the XmlHttlRequest object
Cuga