Exceptions and logging
Moderator: General Moderators
Exceptions and logging
I'm creating a library in which I use exceptions a lot for the errors.
I've also created a simple observer pattern for logging, but I wonder if the logging is needed when I throw exceptions.
Should my library facilitate a way for the user to hook his own logging code, or should I just ignore logging completely and use exceptions instead?
(Ie. let the user catch the exceptions and then log their messages)
I've also created a simple observer pattern for logging, but I wonder if the logging is needed when I throw exceptions.
Should my library facilitate a way for the user to hook his own logging code, or should I just ignore logging completely and use exceptions instead?
(Ie. let the user catch the exceptions and then log their messages)
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Exceptions and logging
I guess it would depend on the type of errors you are catching with exceptions. Fatal errors like file permissions, etc...might be useful to log. Maybe you could just add logging code in the catch block?
Re: Exceptions and logging
That was what I'm wondering. In my library I (almost) don't have any try-catch blocks at all, so I wonder if there would be any benefit to log an error (via the observer-like thing I've made) before passing it off as an exception?
Maybe I should log things which aren't fatal? (I have very very few of those) Or should I just throw an exception to be consistent?
Maybe I should log things which aren't fatal? (I have very very few of those) Or should I just throw an exception to be consistent?
Re: Exceptions and logging
In my opinion it should log only in debug mode
\
Well, it hardly depends of how error can occur. I mean for example there can be an exception that an image can't be created, and it can occur on 5 different places in the function... it can be pointless to throw exception about the internals - why exactly the image can be created, but to throw just that the operation failed. And in this case, a log showing the entire process and which step failed might be useful.
Well, it hardly depends of how error can occur. I mean for example there can be an exception that an image can't be created, and it can occur on 5 different places in the function... it can be pointless to throw exception about the internals - why exactly the image can be created, but to throw just that the operation failed. And in this case, a log showing the entire process and which step failed might be useful.
-
alex.barylski
- DevNet Evangelist
- Posts: 6267
- Joined: Tue Dec 21, 2004 5:00 pm
- Location: Winnipeg
Re: Exceptions and logging
Logging isn't something I would want done by a 'library' it's application specific so unless your including a bootstrap with your library I would leave the logging to the client developer. Basically let them specify the way they want to log errors, either to DB or file or some remote source, etc. Also whether they want logging for produciton or just test environments, like noted above.
Re: Exceptions and logging
It is a kind of bootstrap, you register a function/method which will receive the log messages.
But usually I throw an exception right after I've logged an error, I can just remove the error logging in that case as the user will get the exception.
Which means that I can remove all error logging.
Exceptions have nice stack traces and everything, so debug messages aren't so usable in that respect—for me as the library developer, that is
So debug messages, what kind of information may be useful for the library user? (It is my Object-Relational-Mapper and database abstraction)
But usually I throw an exception right after I've logged an error, I can just remove the error logging in that case as the user will get the exception.
Which means that I can remove all error logging.
Exceptions have nice stack traces and everything, so debug messages aren't so usable in that respect—for me as the library developer, that is
So debug messages, what kind of information may be useful for the library user? (It is my Object-Relational-Mapper and database abstraction)
- Ollie Saunders
- DevNet Master
- Posts: 3179
- Joined: Tue May 24, 2005 6:01 pm
- Location: UK
Re: Exceptions and logging
How does this sound?: Bundle a logger object with the thrown exception and trigger the log with something akin to:
Actually that if (!$e instanceof ... stuff should probably be within $e. So you just have:which returns $this if instanceof self and does the newFromStndPhpExp() stuff otherwise.
I can elaborate this if I'm being unclear.
Code: Select all
set_exception_handler(function($e) {
if (!$e instanceof YurExp) { $e = with(new YurExp)->newFromStndPhpExp($e); }
if (!$e->doLog()) { echo $e->logFailReport(); }
echo $e->report(); });Code: Select all
$e = with(new YurExp)->newFromExp($e);I can elaborate this if I'm being unclear.
Re: Exceptions and logging
Well, why should I bundle a logger object if the user already has his own exception logging code (eg. in the case of a framework)?
I don't really think this is a good idea for a library, as the user needs to learn how to handle those loggers too.
It is a lot easier to treat the exceptions from my lib as normal exceptions without anything special (as a logger).
I don't really think this is a good idea for a library, as the user needs to learn how to handle those loggers too.
It is a lot easier to treat the exceptions from my lib as normal exceptions without anything special (as a logger).
Re: Exceptions and logging
Most libraries provide the option of throwing exceptions or just logging silently. The reason you might want to include a form of logging in your library is that you don't want users to have to go through the source to inject logging logic - that is both tedious and makes upgrading to a newer version difficult. Provide an interface to receive a full stack of error messages in case exceptions are off, and allow users to use their own logging solutions to integrate with it.
Re: Exceptions and logging
How would the optimal implementation of an error stack look like?
And how should I replace exceptions with the error stack? What are the benefits?
Personally I think the exceptions are good, because they send their error directly to the programmer/user.
Because it is a database abstraction I'm creating, I think it is important that the user receives the errors as early in the process as possible, to prevent the code from continuing to run after an error has been encountered.
And how should I replace exceptions with the error stack? What are the benefits?
Personally I think the exceptions are good, because they send their error directly to the programmer/user.
Because it is a database abstraction I'm creating, I think it is important that the user receives the errors as early in the process as possible, to prevent the code from continuing to run after an error has been encountered.
Re: Exceptions and logging
I use exceptions too in my code, but I'm aware that plenty of developers don't. If you're building a library you should consider accommodating multiple styles.
This way you leave the error handling to the discretion of the user.
In my opinion, the optimal *non exception* stack would be an array of errors, each error being an array of messages. For example:
You can replace the associative keys with numerical codes, which is common practice.
Code: Select all
$db = new Database(array('throwExecptions' => false));
if( $db -> connect() ) {
//Success!
} else {
$errors = $db -> getErrors();
//Display / log errors, redirect or ignore
}In my opinion, the optimal *non exception* stack would be an array of errors, each error being an array of messages. For example:
Code: Select all
$errors = array(
0 => array(
'hostname' => 'Hostname was not specified',
'credentials' => 'Credentials are invalid',
'service' => 'MySQL service was not found'
)
);Re: Exceptions and logging
So it is something like this:
I think exceptions make it a lot easier:
+ they enable the user to just catch special errors, so a connection error can eg. be sent to the main error handler, while a query error is handled locally.
So I'm a bit skeptical to this error stack. What are the real benefits?
From what I see it is just more work and makes it more complex to use.
Code: Select all
if($c = Db::getConnection())
{
if($r = $c->query('Somequery')) // what if the query returns false?
{
// some code
}
else
{
// something:
var_dump(Db::getErrors());
}
}
else
{
// something:
var_dump(Db::getErrors());
}Code: Select all
try
{
$c = Db::getConnection();
$c->query('somequery');
// some code
}
catch(Db_Exception $e)
{
// dumps eg. a Db_Exception_InvalidConfig
var_dump($e);
}So I'm a bit skeptical to this error stack. What are the real benefits?
From what I see it is just more work and makes it more complex to use.
Re: Exceptions and logging
The problem with exceptions is that they -
1. Stop execution if not caught (fatal error)
2. Provide a lot of information that might not be relevant in the stack
They are useful for debugging / developing, but for a plugable library you might just want to know what went wrong and not start to look through a series of files and line-numbers to understand what you did wrong.
As I said, I do use exceptions myself. But there developers who don't, and if you're planning on having those use your library you should be willing to accommodate...
1. Stop execution if not caught (fatal error)
2. Provide a lot of information that might not be relevant in the stack
They are useful for debugging / developing, but for a plugable library you might just want to know what went wrong and not start to look through a series of files and line-numbers to understand what you did wrong.
As I said, I do use exceptions myself. But there developers who don't, and if you're planning on having those use your library you should be willing to accommodate...
Re: Exceptions and logging
I think the stop execution thing is good in this case, because it prevents bad things from happening.
Eg. an insert fails, then the user tries to add a few rows which are related with the auto-incremented id of the inserted row.
That would mean it will either violate constraints or it will produce orphaned rows.
I think I'll use warnings (E_USER_WARNING or E_USER_NOTICE, via trigger_error()) for the non fatal things, then it won't be too much work.
Does that sound ok?
Eg. an insert fails, then the user tries to add a few rows which are related with the auto-incremented id of the inserted row.
That would mean it will either violate constraints or it will produce orphaned rows.
I think I'll use warnings (E_USER_WARNING or E_USER_NOTICE, via trigger_error()) for the non fatal things, then it won't be too much work.
Does that sound ok?
Re: Exceptions and logging
You are taking away the developers ability to decide what should stop execution or not. That is my point - that people have separate methods of handling errors.
In my opinion using trigger_errors() is worse, since you can't "catch" it like you do with exceptions (aside from creating a custom error handler). That means the developers has to set it his own checks to avoid your library from throwing errors
In my opinion using trigger_errors() is worse, since you can't "catch" it like you do with exceptions (aside from creating a custom error handler). That means the developers has to set it his own checks to avoid your library from throwing errors