Testing

Tests now match API changes.
The server doesn't provide exceptions in the client side code. An exception is more than just an error code, it's a specific function of a programming language. Read more about that concept here: http://en.wikipedia.org/wiki/Exception_handling

When an exception occurs within the server it has a handler that returns an HTTP Response back to the client with an appropriate status code: Read more about HTTP status codes here: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

When the client gets ANY response from the server the response has one of these status codes. If the server threw and exception and returned an HTTP Response (say from an error 403 bad authentication) the client will only see "Server responded with the status 403: Permission Denied.

So in the _post_data and _get_data functions we've added a bunch of if statements that look at these status codes. If a bad status is returned by the server, we examine it then throw an exception in the client. Which is where these exceptions come into play.

One of the important factors of exceptions is what is called "stack unwinding" every language does this in some way, but Python is very similiar to C++ in that regard. You can read more about stack unwinding here: http://msdn.microsoft.com/en-us/library/hh254939.aspx

The general reason for throwing an exception is that each function on the stack is popped off the stack until a handler for that specific exception is found. That is no code after the exception was thrown will be run until the exception is handled in some way. If none are found then the program exits with an error. In Python a traceback (stack trace) is shown. If an exception is found and handles the error in some way program execution can continue. In this way you can think of exceptions kind of like the keyword 'break' except instead of being used for loops, exceptions are for functions.

I hope that clears some things up for you.