Glyn
Glyn

Reputation: 1995

Error message from Java to Ajax is not returned properly

When the java program does not find the required information I want to return an appropriate error message (could be one of a number of identified reasons). My java code is:

}else{
    response.sendError(response.SC_BAD_REQUEST, "Captcha description not correct");
    response.getWriter().write("Captcha description incorrect.");
}

And the ajax is:

$.ajax({
    type: "POST",
    url: "AccountRecoveryQuestionsView",
    cache: false,
    data: $(questionForm).serialize(),
    success: function(data){
        $('#ajaxGetUserServletResponse').text(data);
    },
    error: function(data) {
        $("#accountName").focus();
        //$('#ajaxGetUserServletResponse').text('An error occured validating the questions.');
        $('#ajaxGetUserServletResponse').text(data);
    }
});

The error function is triggered; however, the message is not displayed.

I have changed the code to:

          statusCode: {
                400: function(jqXHR, textStatus, errorThrown){
                    alert(jqXHR.status);
                    alert(textStatus);
                    alert(errorThrown);
                    $("#accountName").focus();
                    $('#ajaxGetUserServletResponse').text(errorThrown);
                }
            },

And the result is 400, error, blank.

I have changed the ajax to:

          .fail (function(jqXHR, textStatus, errorThrown) {
                alert(jqXHR.status);
                alert(textStatus);
                alert(errorThrown);
                alert(jqXHR.statusText);
                alert(jqXHR.responseText);
                $("#accountName").focus();
                //$('#ajaxGetUserServletResponse').text('An error occured validating the questions.');
                //$('#ajaxGetUserServletResponse').text(errorThrown);
                $('#ajaxGetUserServletResponse').text(jqXHR.responseText);
            });

And alert(jqXHR.responseText); is returning:

<!doctype html><html lang="en"><head><title>HTTP Status [400] – [Bad Request]</title><style type="text/css">h1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} h2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} h3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} body {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} b {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} p {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;} a {color:black;} a.name {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status [400] – [Bad Request]</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Captcha description not correct</p><p><b>Description</b> The server cannot or will not process the request due to something that is perceived to be a client error (e.g., malformed request syntax, invalid request message framing, or deceptive request routing).</p><hr class="line" /><h3>Apache Tomcat/8.5.15</h3></body></html>

How do I just get the error message "Captcha description not correct". This is contained in the above.

Upvotes: 0

Views: 1170

Answers (3)

Kristin
Kristin

Reputation: 1391

The HttpServletResponse object should not be written to after #sendError has been called, as stated

If the response has already been committed, this method throws an IllegalStateException. After using this method, the response should be considered to be committed and should not be written to.

hence:

response.sendError(...);
response.getWriter().write(...); // Should not be done

You should use the static field access of the error codes. In your code, you use response.SC_BAD_REQUEST, when you should use HttpServletResponse.SC_BAD_REQUEST. Writing the int code yourself, e.g. sendError(400, ...), does not change the outcome.

The .error call for the $.ajax-function in jQuery, has been removed since version 3.0, so do not use it. Instead, you should use .done, .fail and .always. .done is the equivalent of .success, while .fail is the equivalent of .error, and .always is kinda like a finally-block in a try-catch (will, as the name implies, always run, regardless).

$.ajax always returns a jQuery XMLHttpRequest object, jqXHR. You can thus run method calls directly on the $.ajax-call, like

var jqxhrobj = $.ajax({
    type: "POST",
    url: "AccountRecoveryQuestionsView",
    cache: false,
    data: $(questionForm).serialize()
})
.done(function(jqXHR, textStatus, errorThrown) {
    // Success here
    $('#ajaxGetUserServletResponse').text(jqXHR.responseText);
})
.fail(function(jqXHR, textStatus, errorThrown) {
    // Fail, do something about the error
    // Since you have several error codes you want to handle
    // you could for instance use a switch case
    switch(jqXHR.status) {
        case "400":
            // It might be an int, or even "400 Bad request",
            // change accordingly

            // Do something to handle the error
            break;
        default:
            // Handle errors not specified with a case
            break;
    }
});


// Later in the js code

jqxhrobj.always(function() {
    // Execute something here, regardless of success/failure of the $.ajax-call
});

Further information on the jqXHR object can be read here.

The responseText will contain a fully formatted html-output, with head, body and so on. If you look at the body of the responseText, it looks like this:

<body>
    <h1>HTTP Status [errorCode] – [errorCode description]</h1>
    <hr class="line" />
    <p><b>Type</b> Status Report</p>
    <p><b>Message</b> [message passed as 2nd argument in the sendError-call]</p>
    <p><b>Description</b> [full errorCode description]</p>
    <hr class="line" />
    <h3>Apache Tomcat/8.5.15</h3>
</body>

You could use .find (see here) on the jqXHR.responseText - find the p-tags inside of the body. You should have 3 elements returned; the message will be inside the 2nd result element. You might want to do some sort of substr, to get rid of <b>Message</b>.

A simple but naive approach, that relies on the output to always have exactly the same structure:

var message = jqXHR.responseText.find("p:eq(1)").text();
// text() will not return the <b>-tags, just "Message [msg passed as argument]"
// We'll just substr from the end of "Message"
message = message.substr(7));
// Remove any leading/trailing whitespace
message = message.trim();
// message now contains the error message from #sendError
alert(message);

Upvotes: 1

Harshita Sethi
Harshita Sethi

Reputation: 2125

you can return the following

Response.status(500).entity("Captcha description incorrect. ").build();

Modify the error code based on your requirement,

Upvotes: 0

davidluckystar
davidluckystar

Reputation: 938

Try to flush and close your writer

...
response.getWriter().flush();
response.getWriter().close();

If it didnt help, make sendError call the last one like this

response.getWriter().write("Captcha description incorrect.");
response.sendError(response.SC_BAD_REQUEST, "Captcha description not correct");

Upvotes: 0

Related Questions