Re: Common way of error handling?

From: Date: Sat, 13 May 2000 15:11:54 +0000
Subject: Re: Common way of error handling?
References: 1 2 3  Groups: php.pear 
Request: Send a blank email to php-pear+get-102@lists.php.net to get a copy of this message
Ulf Wendel wrote: > > Stig Bakken wrote: > > > > Ulf Wendel wrote: > > > > > > Hi! > > > > > > Is there a common way of error handling in PEAR modules? > > > > There isn't. Personally, I like Java's exceptions in that you throw > > objects, and that you can subclass exception classes. DB has a somewhat > > abstracted error concept (where the definition of "error" currently is > > "negative integer"). It would make sense to steal some from Java and > > extend this to make the error concept "an object of this class (or a > > subclass)" and make it general at the same time. > > I also like the way to adopt the java way (again). I've played a lot > with the problem of error handling. I started somewhat similiar the way > you have choosed in DB just not that elegant. This way has some > problems: > > - return values suddenly change their type > - you have long lists (array or defines) with error messages > > Later on I decided to have one class "error" that handles errors. I > passed the error message and the error number to it an let it do the > work. It was up to "error" to supress the message, print it or even halt > the script. > > With PHP we can't realize the java way, because we don't have try-catch > and throw. But we could overtake some ideas from the class hierarchie, > mix the exception and the execption handling within one class hierarchie > to get some of java features. (Puh - he seens to be drunk, what does he > mean?) > > Let's look at the key features we need: > > 1. It must be easy to create an exception within a module. > 2. All PEAR modules should have a predefined default behaviour. > 3. Each PEAR module must be able to override the predefined behaviour. > 4. Each PEAR module must be able to control the reaction on an exception > (show, halt), override its own default behaviour. > 5. The user should be able to override the default behaviour of a > module. > > Extended "features": > > 6. There're predefined exceptions. > 7. There're different "levels of exceptions": error, warning, notice). > 8. There're diffent "kinds of exception": > - Runtime (caused by the module itself) > - User (caused by the programmer when using the module) > - IOException > > +++ creating an exception +++ > > Creating an exception must be as easy as possible and the programmer > must be able to decide wether to rely on the default exception handling > or to override it. > > + Syntax > new pear_NameOfException ( [string $message, int $errno , string > $filename, int $linenum, bool $auto_handle ]); > > + Examples > > <?php new pear_notice("my notice"); ?> > > Create a simple note. It's up the the default pear_notice class how to > handle it. I suggest don't show, don't halt. > > <?php new pear_warning("my warning", -1000, __FILE__, __LINE__); ?> > > Create a warning, provide the exception handler with an error code, the > current filename and the current line number. It's up to the default > pear_warning class how to handle it. I suggest show, but don't halt. > Show always means "show all possible informations, no matter if $errno, > $file or $linenum are defined". > > <?php $err=new pear_error("my_error", -1, __FILE__, __LINE__, false); ?> > > Create an Error, provide the exception handler with an error code, the > default filename and the current line number. The default exception > handling is switched off. > > Now you can decide to call: > - $err->handle(), default handling > - $err->show(), show the error but don't halt > - $err->halt(), show the error and halt > > As your PEAR modules controles the bahaviour, you can exit your function > returning a value of the promised type or halt if necessary. > > +++ default behaviour of PEAR modules +++ > > We can gain default behaviour if we use polymorhism. > > Up to this point we haven't thought about the class hierarchie not even > on what classes we need. We have to start with it now to understand my > thoughts. > > We have two basis tasks: > - defining exceptions > - handling defined exception > > Translating this to the oo world gives something like this (kind of UML > notation): > > --------------------- > | exception handler | > | | > | show(), halt() | > --------------------- > ^ 1 > | > | 1 > --------------------- > | exception | > | | > | create exception | > --------------------- > > The default PEAR behaviour resides on level three: > > --------------------- > | PEAR | > | exception handler | > --------------------- > ^ 1 > | > | 1 > --------------------- > | exception handler | > | | > | handle() | > --------------------- > ^ 1 > | > | 1 > --------------------- > | exception | > | | > | create exception | > --------------------- > > On level four I placed predefined PEAR exceptions such as PEAR_Warning, > PEAR_Error, PEAR_Notice: > > --------------------- > | PEAR_Warning | > | | > --------------------- > ^ 1 > | > | 1 > --------------------- > | PEAR | > | exception handler | > | | > | handler_warning() | > | handler_error() | > | handler_notice() | > --------------------- > [...] > > On level four a class is usually pretty small, there's only a > constructor (see creating an exception). The constructor passes most of > its arguments to exception::exception() and calls > pear_exception_handler::handle() if requested (default). That's all. > > Level four is a keypoint. I can't make up my mind how it should look > like. Does the class tree branch on the "level of an exception" (notice, > warning, error) and stop as shown or do we follow the Java way? > > Java has no need to mix the event handling and event creation together. > They have try-catch and throw, we do not. In Java there is no need to > define "levels of exceptions". It's up to who ever catches the exception > to "rate" it, to give it a certain "level" (notice, warning, error). > Java branches the tree at this point on the "kind of an exception" > (Runtime, IOException). Translated to the PHP/PEAR world we would get > something like this if we like the idea of "levels": > > > exception::exception_handler::pear_exception_handler::pear_runtime::pear_runtimeerror::pear_wrongparamcount > > > exception::exception_handler::pear_exception_handler::pear_ioexception::pear_ioerror::pear_direrror > > ... somewhat to complicated. > > The concept of "levels" (notice, warning, error) seems to be a must in > the PHP world. I suggest rating it that high the class modell stops on > level four. Introducting a deeper class modell would mean overdoing it. > > exception::exception_handler::pear_exceptiion_handler::pear_warning::pear_io > exception::exception_handler::pear_exceptiion_handler::pear_warning::pear_runtime > exception::exception_handler::pear_exceptiion_handler::pear_error::pear_io > > Instead of this preferr a "faulty" compromise: default exceptions stay > on level four: > > pear_notice, notes that fit nowhere else > pear_warning, warnings that fit nowhere else > prear_error, errors that fit nowhere else > pear_ioexception, an error while dealing with io > pear_runtime, a warning that is cause due to wrong use of functions > > +++ default behavoir of a module +++ > > Each PEAR module can override the default PEAR exceptions classes and > even more provide new exceptions, although I don't thing that this is > really necessary for most of the smaller modules. > > +++ the user should be able to control the exception handling +++ > > This is necessary e.g. for customizing the handleException() methods > that prints the exception, or instance vars such as show_error or > halt_on_error. The user could even want use mail() to get informed by > e-mail whenever an error occurs. > > Customization can be done by modifing the exception classes of the > module. Experienced users might even modify the pear exception classes. > > +++ API +++ > > He're an API demo of the sketched modell: > > <?php > class my_pear_module { > function createNotice() { > new pear_notice("my_notice"); > } > > function createWarning() { > new pear_warning("my_warning", 1000, __FILE__, __LINE__); > } > > /** > * @return bool $ok > */ > function createError() { > if (true) { > $err = new pear_error("my_error", 1, __FILE__, __LINE___, false); > $err->show(); > return false; > } > return true; > } > } > > my_pear_module::createNotice(); > my_pear_module::createWarning(); > my_pear_module::createError(); > ?> > > The class hierachie is pretty simple (as shown above). It takes less > than 200 loc in PHP, it's flexible and can be configured widely. It does > not come with major restrictions. How about it? > > Ulf > From what I see and understand, I like it. However, I'd like a concrete example of how it might be used within PEAR and then how the user would catch the error (I saw the example above, I'm just asking for a more concrete example.) Sterling

« previous php.pear (#102) next »