views:

179

answers:

1

I have an application which relies on a soap server to produce content. Additionally authentication to the site is based on a seperate LDAP server. Obviously if either of these are down or not responding the site is down.

I am trying to lay out a design such that I can have error reporting for site admins and also give a nice message to user's in the case that the site is down. Error reporting is really just an email, database insert or log to text file on server of PHPs $_COOKIE, $_SERVER, $_SESSION, $_REQUEST along with potentially a SoapFault exception. This information would aid me in debugging any potential problems with the site if they occur.

Currently, my site is designed as follows:

SoapClientInterface (defines soap functioanlity)
      / \
       |
       |   implements
       |
Client (the client implementing the interface, try/catch blocks on all soap calls here) 
      / \
       |
       |  extends
       |
 Authorization (asserts soap objects returned from server/ requests going to server 
               are appropriate for the user performing the request) 
      / \
       |
       | extends
       | 
  {all children classes using the soap interface defined on this level} 

From the poor diagram above :-) I have a class Client which encompasses all of my try catch blocks for soapfault exceptions and am wondering the best way to do two things with the catchs: 1. notify user an action has failed (all of my functionality is in if/else blocks and if I determine an operation has failed I re-direct user to a status page and inform them that their action has failed.
2. report the situation to site admins for debugging (this functionality at the moment is a simple function defined in status page that when status page gets an error code we dump the Cookier, Server, Session, and Request variables and email this off to site admins.

Any suggestions on this would be appreciated or if you need clarification please ask...

Thanks.

EDIT: In my experience with web programming my applications usually display status of user actions on the page in which the action takes place and do not re-direct elsewhere. This is the first time I have coded an application to perform a user action and redirect to a separate page for all status messages. Should I be kicking myself for doing it this way, does anyone see merit in having a single status page for all site actions or having a class/function that reports status on the page in which the action took place? (I am asking this in regards to thinking about the design of status page on its own and how to report errors and what not.)

+1  A: 

Well, personally I think it depends on the error. In my experience, there are three types of exceptions. Those that you can ignore, those that you can work around, and those that you use to terminate execution (A file_not_found exception can be ignored if you're just trying to delete the file, a resource_not_available exception may be able to be worked around if there are alternative sources for the resource, and a database_connection_failure exception would require termination of the app unless you had a backup)... Which type of exception was caught will dictate what you do with it.

Personally, I install a global exception handler... Then, in my catch block I can choose whether to clean up the request, handle it differently, continue on (if it's a recoverable exception), or re-throw the exception if I can't handle it properly (Query error, etc). If the exception makes it to the top of the stack (the global handler), then I log the error (I use a database table for this) and throw a 500 internal server error.

As far as redirecting for errors, I can't stand that. If the error is a temporal error, then why can't I just refresh the page? Why must I go back (if I even can) to try again...

As long as you output buffer properly, you should almost always be able to render an error page without displaying any sensitive info to the user (I say almost, since you can't render anything for a fatal error)... Otherwise you're breaking HTTP spec (Since you are saying there's a temporary redirect from the current page where the error occurred rather than the proper "an error occurred" status header)...

ircmaxell
@ircmaxell first off thanks for the thoughtful comments, appreciated. Secondly, lets say for example in the case of a soapfault exception where a user tried to perform an update, in that case you suggest just reporting an error occured to the user, leave them on the form and let them potentially try to resubmit?
Chris
@ircmaxell so to use set_exception_handler() I can just define my own function to handle all of what I want? Define error reporting in this custom exception handler, redirects if needed, etc etc? And then just have my class Client throw exceptions? I am not totally understanding how to get a custom handler into my design in the best way.
Chris
Well, yes and no. I would not leave them on the form unless the problem was with their input. I would leave them on the URL, and set the status header to `500`, and display a page saying that "Your request could not be handled at this time due to an unexpected server error. Please try again later. If this error persists, please contact blah..." Assuming that you don't have tight CSRF protection (Meaning deleting the session key for the csrf token on submission), they can just refresh the page to try again. The problem with redirecting, is that they have no idea where the error happened...
ircmaxell
@ircmaxell thanks appreciate your help
Chris
The exception_handler is a function that is called if nothing "catches" the exception (It bubbles all the way up the stack to the root). Basically when PHP would normally fatal error for an unhandled exception, it'll call the callback specified in `set_exception_handler`. That way, you can do all of your logging there, and the generation of the error page. This avoids having to wrap everything in a giant try/catch block just to avoid the "unhandle exception" fatal error...
ircmaxell
Is it possible to use a class::function opposed to just a function? Not required but just curious on my part and did not see anything googling that said you could or could not for that matter. Something like set_exception_handler(ErroClass::staticFunction);
Chris
Absolutely. It accepts a standard callback, so you can do `array($foo, 'bar')` for an instance method, or `array('Foo', 'bar')` for a static method... (I try to stay away from the `Class::method` callback syntax). You could even use an anonymous function if you would like...
ircmaxell