Re: Common way of error handling?
| From: | Sterling Hughes | 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