My jquery .ajax() keeps invoking .fail() handler when result is successful, why??

Here's how my jQuery .ajax() call looks like on my login.php page:

$.ajax({
                            method: "POST",
                            url: "/_includes/_db/processLogin.php",
                            dataType: "json",
                            data: { username: $("#txtUserName").val(), 
                                    password: $("#txtPassword").val() }
                        })
                        .done(function(data, textStatus, jqXHR) {
alert("It hit done.");
                        })
                        .fail(function(jqXHR, textStatus, errorThrown) {
alert(jqXHR.status); // IT KEEPS LANDING HERE AND PRINTS OUT 200, WHICH IS OK.
                        });

Open in new window


The PHP script (processLogin.php) contains this code excerpt:

try {
        $db = DB::getPDOConnection();
        // Turn on Exception throwing
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    } catch (Exception $e) {
        $userMessage = "FATAL ERROR!";
        $arrResponse = array('result'=>'fail', 'message'=>$userMessage);
        echo json_encode($arrResponse);
        exit;
    }

Open in new window


Now I intentionally misspelled the host name to force an error, and I have confirmed that code execution does reach the catch block. But given the way it is, the .ajax() on the client side is firing off the .fail() handler instead of the .done(), and I can't figure out why. I could've sworn this used to work, and it just stopped working all of a sudden.

Can anyone see any reason why the .ajax() would fire the .fail() handler instead of the .done()?

Thanks.
elepilAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Ray PaseurCommented:
Check the last example on this page.  They do not use chained methods.
http://api.jquery.com/jquery.ajax/
elepilAuthor Commented:
Ray,

I don't know the purpose of your providing that link, nor do I know what you mean by "chained" methods. Are you talking about my throwing Exceptions again? Because that is on the PHP side. As far as the .ajax() call, I imagine all it should care about is what I'm echoing out of my PHP script, right?
Dave BaldwinFixer of ProblemsCommented:
I tried the 'jqxhr' demo code on that page.  I had a problem with the 'success' code because the PHP page was sending it off somewhere.  I created an even simpler PHP page that only echoed a  short string.  On another question, dataType: "json", was causing problems because the returned data was not being used as JSON data.  Try commenting dataType: "json", out and see what you get.  If you are not returning JSON formatted data, that may be considered a 'fail'.
Fundamentals of JavaScript

Learn the fundamentals of the popular programming language JavaScript so that you can explore the realm of web development.

Ray PaseurCommented:
I think you will see the purpose of that link if you look at the last example on the page, reproduced here for your convenience:
var menuId = $( "ul.nav" ).first().attr( "id" );
var request = $.ajax({
  url: "script.php",
  method: "POST",
  data: { id : menuId },
  dataType: "html"
});
 
request.done(function( msg ) {
  $( "#log" ).html( msg );
});
 
request.fail(function( jqXHR, textStatus ) {
  alert( "Request failed: " + textStatus );
});

Open in new window

Notice how the example defines request.done() and request.fail() as separate closures.  Chained methods are the way your original code snippet showed the .done() and .fail() methods written as part of the $.ajax() statement.  That's the client-side part of things.  It might be easier to follow the example in the online manual.

In the PHP code snippet, it appears that your script may echo what looks like a failure response (if an exception is thrown), but I can't see where it runs a query, so I'm a little confused about how it might return data.  And the PHP definition of success or failure is not the same as the jQuery definition.  This article explains some of the ideas:
https://github.com/jquery/api.jquery.com/issues/49

When I develop AJAX-type interactions, I start by developing the server-side of the action.  You can test this from the browser address bar if you use $_REQUEST, which covers both $_GET and $_POST.  Your URL parameters can be injected directly into the request variables.  Once you're satisfied that the script works, change out $_REQUEST and use only $_POST.
elepilAuthor Commented:
Dave,

I should mention that this code has been working for a while now. It has been part of my procedure to test my error-handling routine by intentionally misspelling my server name from 'localhost' to 'localhos' to make it bomb out. It has always been invoking the .done(), not the .fail(). I am totally perplexed why it's doing this now, and I find it even more incredulous that I now should change the code when it was working fine before. Something else is causing this.
Dave BaldwinFixer of ProblemsCommented:
This demo from the middle of the page works fine.  Is the formatting different and I just don't recognize it?

/ Assign handlers immediately after making the request,
// and remember the jqXHR object for this request
var jqxhr = $.ajax( "example.php" )
  .done(function() {
    alert( "success" );
  })
  .fail(function() {
    alert( "error" );
  })
  .always(function() {
    alert( "complete" );
  });
 
// Perform other work here ...
 
// Set another completion function for the request above
jqxhr.always(function() {
  alert( "second complete" );
});

Open in new window

Dave BaldwinFixer of ProblemsCommented:
elipil, look for typos...  Also... I never take it as a guarantee that just because the code was working that I didn't miss something that didn't work but was always in there.  I've done that a couple of times.  When the right 'trigger' comes along, it failed.
Dave BaldwinFixer of ProblemsCommented:
Is "/_includes/_db/processLogin.php" actually returning JSON formatted data?
elepilAuthor Commented:
Dave,

Yes, and I know this because I set a breakpoint on where my array was being given the two elements of 'result' and 'message'. It executes the echo json_encode($arrResponse) just fine, too, even the final 'exit' statement. So despite everything looking normal to me as I step trace it line by line, it ends up in the .fail() handler back on the .ajax() side.

I get so frustrated with PHP/jQuery/JavaScript when these things happen. I thought I was done with this part, and now I have to revisit it again.
Dave BaldwinFixer of ProblemsCommented:
When you mix them all together, you Never get away from it.  How do you think Ray and I stay employed?  There is always something...

Since an AJAX POST (or GET) is just a different way of doing an HTML <form>, sometimes I create a simple form page to POST and display the returned data.  That would give you another view to the problem that does not include javascript or AJAX.
Ray PaseurCommented:
I am looking at the code here:
http://www.experts-exchange.com/viewCodeSnippet.jsp?refID=28675907&rtid=10&icsi=2

Here it is annotated with comments.  It does not make sense to me because it never runs a query nor returns any data unless there is an Exception.

// WRAP THE FOLLOWING STATEMENTS IN A TRY / CATCH BLOCK
// TRY TO DO SOMETHING
try {

    // THIS APPEARS TO RUN A STATIC METHOD CALL TO ASSIGN A VALUE TO THE $db VARIABLE
    $db = DB::getPDOConnection();
    
    // THIS APPEARS TO SET SOME ATTRIBUTES ON THE $db OBJECT
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
// IF NOTHING THREW AN EXCEPTION, THE CATCH BLOCK WILL NOT BE RUN
// ONLY IF SOMETHING IN THE TRY BLOCK THREW AN EXCEPTION WILL WE EVER SEE THIS CODE EXECUTEDD
} catch (Exception $e) {
    $userMessage = "FATAL ERROR!";
    $arrResponse = array('result'=>'fail', 'message'=>$userMessage);
    echo json_encode($arrResponse);
    exit;
}

// SO AFTER THE TRY BLOCK IS EXECUTED, THE SCRIPT WILL BE HERE, DOING WHATEVER IS CODED HERE

Open in new window

Dave BaldwinFixer of ProblemsCommented:
In an important way, what you're dealing with now is the Important stuff of programming, especially for the web.  I have a custom shopping cart that I was hired to work on in 2008.  It is used on four different web sites... but of course, each site has a somewhat customized version even though they all have to do the same things.  The site owner frequently wants changes made and features added.  We've added a lot of javascript and 'user features' over that time.  Last year, after 'working' for 6 years, we finally made a change that exposed an error that had been there since the original code in 2008.  It took six years before we did something that made it take the error branch in the code.

I get hired by people who need someone to modify their existing PHP code.  The troubleshooting skills that I learned in electronics have helped me a great deal in doing that.  Creating code is one thing.  Going in and Fixing or Modifying code is in my opinion a much greater skill.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ray PaseurCommented:
@Dave: ^^ +1 for that !
elepilAuthor Commented:
I recently had to reinstall my Windows OS. The day before that, I did one whole day's work that enhanced my error-handling routines which I unfortunately didn't backup before my hard drive crash. But everything was working PERFECTLY. After a lot of grief from having to bring my system back to the shape it was prior to the crash, I started recreating what I lost, and this happens. This did NOT happen before.

Dave, I know what you're talking about, I've had bugs that didn't appear until 1 1/2 years later. But this is different. NO CHANGES were made that could even have this effect. After I do "json_encode($arrResponse);", it's also out of my hands. What happens from that point until it reaches the front end is out of my reach. So I really don't know what I can do.

Ray, you don't need to see my query. My sample could very well just have been a straight array creation of anything followed by a json_encode($array) function call, and that's when this issue comes up.
Ray PaseurCommented:
Ray, you don't need to see my query.
Really?  OK, I'm out.  

I do not depend on rumors or expectations or anything like that -- I depend on test-driven development because I know it works, and so does the rest of the professional industry.  So when the question is postulated with unproven assertions, I know it's time to let someone else try to help.  The SSCCE is a really good idea; I can install it and test it.  And in my experience (more years than I care to admit) anything less is just irresponsible.

Best of luck with your project, ~Ray
elepilAuthor Commented:
Ray,

You're totally missing the point of the problem. It so happens I was using a query to cause the catch block to execute which contained the code to echo a json string back to the client.

Didn't you see Dave's post that he copied/pasted my code and he got the same thing? I'll bet you he has no query.
elepilAuthor Commented:
You know what, screw this. This only happens when I changed my 'localhost' to 'localhos' to force a database connection failure. All other error handling sections function normally without this issue. I have no idea why this is happening, and I really shouldn't spend more time on this anymore. I'm falling behind on my project.

Thanks to all who responded.
Dave BaldwinFixer of ProblemsCommented:
Didn't you see Dave's post that he copied/pasted my code and he got the same thing?
You misunderstood me.  I copied the code from http://api.jquery.com/jquery.ajax/ and it worked perfectly.  http://www.dibsplace.com/webdev/jqxhr-function-tests.html

Ray and I are pretty good with code.  When you say that we don't need to see code, that lowers our interest in helping you.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
AJAX

From novice to tech pro — start learning today.