Hi all,
There's been a lot of discussion around whether or not to include
exceptions for core (no class implementations) errors or not. There's been
a lot said on both sides. However, I'd like to pose the question from a
different angle.
Right now, I see the biggest problem with errors currently in PHP is that
there's no easy way of discerning between error types to be able to handle
them. Therefore it's easier to ignore the error than it is to handle it
bluntly. For example, I may want to distinguish between failure modes of
file_put_contents()
. Right now, three types of errors can occur: File not
writable (can't open it), Can't write to file (write failed), and Partial
write only (but certain bytes were written).
http://lxr.php.net/xref/PHP_5_4/ext/standard/file.c#661 Right now, there's
no way short of parsing the error string to even attempt to distinguish
between them (arguably the first two could be treated the same, but the
third could lead to very dangerous situations). Which is non-trivial to say
the least...
So, while I know there's some discontent about having the core raise
exceptions, let me ask the question differently:
Without moving to exceptions, how could the current error and error
handling mechanisms be improved to make the scenario I posted above easier.
To make handling errors just as easy as ignoring them (or preferably
easier)...?
Thoughts?
Anthony
Right now, I see the biggest problem with errors currently in PHP is that
there's no easy way of discerning between error types to be able to handle
them. Therefore it's easier to ignore the error than it is to handle it
bluntly. For example, I may want to distinguish between failure modes of
file_put_contents()
. Right now, three types of errors can occur: File not
writable (can't open it), Can't write to file (write failed), and Partial
write only (but certain bytes were written).
http://lxr.php.net/xref/PHP_5_4/ext/standard/file.c#661 Right now, there's
no way short of parsing the error string to even attempt to distinguish
between them (arguably the first two could be treated the same, but the
third could lead to very dangerous situations). Which is non-trivial to say
the least...
Isn't one of the main points of using Exceptions that you can catch all
exceptions (Exception) or subclasses (hypothetical IOException, etc.) or
very specific ones (hypothetical IOFileOpenException)?So, while I know there's some discontent about having the core raise
exceptions, let me ask the question differently:Without moving to exceptions, how could the current error and error
handling mechanisms be improved to make the scenario I posted above easier.
To make handling errors just as easy as ignoring them (or preferably
easier)...?
I don't wish to derail this thread from the get-go, but what's your
opposition to moving to exceptions?
--
Andrew Faulds
http://ajf.me/
Andrew:
I don't wish to derail this thread from the get-go, but what's your
opposition to moving to exceptions?
I'm absolutely for moving to exceptions. I asked this question as a
thought exercise to see 1. If the current error system can be improved, or
- To identify if it can't, and exceptions really are the better route.
Anthony
I don't wish to derail this thread from the get-go, but what's your
opposition to moving to exceptions?I'm absolutely for moving to exceptions. I asked this question as a
thought exercise to see 1. If the current error system can be improved, or
- To identify if it can't, and exceptions really are the better route.
What you are staying here is really: if we can't improve error handling,
let's break all code out there.
Derick
Derick,
I don't wish to derail this thread from the get-go, but what's your
opposition to moving to exceptions?I'm absolutely for moving to exceptions. I asked this question as a
thought exercise to see 1. If the current error system can be improved,
or
- To identify if it can't, and exceptions really are the better route.
What you are staying here is really: if we can't improve error handling,
let's break all code out there.
Not quite. What I'm saying is that the current situation isn't great, and
that we should find a way of fixing it. If it can be done in a BC manner,
then great. If not, then so be it. But we should consider alternatives...
And there are ways of doing it without breaking "all code out there",
similar to a "use strict" token, and treat it separately per file... Etc...
I'm not making a proposal yet, just wanted to get a discussion going about
the options that we have without immediately jumping to exceptions (I think
that's where it will ultimately end up, but wanted to explore options
first)...
Anthony
On Sun, 02 Sep 2012 03:39:15 +0200, Anthony Ferrara ircmaxell@gmail.com
wrote:
So, while I know there's some discontent about having the core raise
exceptions, let me ask the question differently:Without moving to exceptions, how could the current error and error
handling mechanisms be improved to make the scenario I posted above
easier.
I don't think your specific scenario needs to be improved.
file_put_contents()
is a high level function with coarse error reporting.
If you need to distinguish the problems, you can open the files
separately, and use stream_copy_to_stream()
.
But in any case, for the general problem you're raising -- that false does
not give enough information for handling the error, the solution is
well-established: you have some way of getting the error code. This can be
done either through a dedicated function (like curl_errno, mysqli_errno)
or through extra parameters, like it's done in stream_socket_client()
. And
yes, it's unfortunate we don't have any sort of common interface or even
consistency in this area.
To make handling errors just as easy as ignoring them (or preferably
easier)...?
I don't think that's feasible, except maybe by using checked exceptions
(which most people hate, with good reason). Writing bad exception-based
code and bad error-code-based code is always easy. See the tables here:
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/14/352949.aspx
--
Gustavo Lopes
So, while I know there's some discontent about having the core raise
exceptions, let me ask the question differently:Without moving to exceptions, how could the current error and error
handling mechanisms be improved to make the scenario I posted above easier.
To make handling errors just as easy as ignoring them (or preferably
easier)...?Thoughts?
I think there are other options here. Our current error handling isn't
all that different from how it would be if everything was an exception.
Chances are that common code isn't going to distinguish between the
exceptions anyway and they will end up just doing:
try {
file_put_contents(...);
} catch (Exception $e) {
error_log($e->getMessage());
}
Then the more aware folks will be checking their error logs and noticing
certain errors they may want to handle better and they add explicit
catches for this:
try {
file_put_contents(...);
} catch (NotWritableException $e) {
page_an_op();
} catch (Exception $e) {
error_log($e->getMessage());
}
In our current system the before and after would be:
file_put_contents(...);
And when the same aware person notices a specific condition they want to
handle they change it to:
if(!is_writable(...)) page_an_op();
else file_put_contents()
;
The Exception case runs extra code only when the condition happens while
our current system typically has the check before trying to do the
operation so there is an extra cost for each op, but there are cases
where you really don't want it to even try so there is some advantage
there. Of course a similar check can be added before the call in the
Exception case.
My point here is that these two systems aren't actually that different
and the try/catch approach is certainly more verbose. I would also hate
to end up in the situation where most code has a high-level generic
exception handler that spews huge meaningless stack traces as a
catch-all and so far removed from the context of the actual error that
you can't do anything intelligent about it there.
So how else could you approach it?
My biggest beef with exceptions is that often you end up catching them a
couple of levels above where the error actually occurred and you don't
have any sort of recovery context at that point. Common Lisp had the
notion of conditions and restarts to address this. I always found them a
bit cumbersome syntax-wise, but I liked the idea of condition objects
carrying the context of the error. A condition is similar to an
exception in some ways except it carries contextual data about the error
and it isn't necessarily exceptional/fatal if not handled. This
particular characteristic of condition objects appeal to me for PHP
because it would allow us to migrate everything to conditions, not just
the fatal errors, without breaking everything.
The second part of the Lisp approach is the restart. If you choose to
handle the condition you can also choose to try to gracefully recover by
passing the condition object which includes the context of the error to
an appropriate restart function that lives closer to the code that
actually caused the error. This split allows you to have catch-all type
of condition handlers without losing the ability to do context-aware
error recovery.
I would love to see a proposal from someone who understands
condition-restart systems inside out for how they might be applied to PHP.
-Rasmus
Rasmus Lerdorf wrote:
So, while I know there's some discontent about having the core raise
exceptions, let me ask the question differently:Without moving to exceptions, how could the current error and error
handling mechanisms be improved to make the scenario I posted above easier.
To make handling errors just as easy as ignoring them (or preferably
easier)...?Thoughts?
I think there are other options here. Our current error handling isn't
all that different from how it would be if everything was an exception.
Chances are that common code isn't going to distinguish between the
exceptions anyway and they will end up just doing:try {
file_put_contents(...);
} catch (Exception $e) {
error_log($e->getMessage());
}Then the more aware folks will be checking their error logs and noticing
certain errors they may want to handle better and they add explicit
catches for this:try {
file_put_contents(...);
} catch (NotWritableException $e) {
page_an_op();
} catch (Exception $e) {
error_log($e->getMessage());
}In our current system the before and after would be:
file_put_contents(...);
And when the same aware person notices a specific condition they want to
handle they change it to:if(!is_writable(...)) page_an_op();
elsefile_put_contents()
;The Exception case runs extra code only when the condition happens while
our current system typically has the check before trying to do the
operation so there is an extra cost for each op, but there are cases
where you really don't want it to even try so there is some advantage
there. Of course a similar check can be added before the call in the
Exception case.My point here is that these two systems aren't actually that different
and the try/catch approach is certainly more verbose. I would also hate
to end up in the situation where most code has a high-level generic
exception handler that spews huge meaningless stack traces as a
catch-all and so far removed from the context of the actual error that
you can't do anything intelligent about it there.So how else could you approach it?
My biggest beef with exceptions is that often you end up catching them a
couple of levels above where the error actually occurred and you don't
have any sort of recovery context at that point. Common Lisp had the
notion of conditions and restarts to address this. I always found them a
bit cumbersome syntax-wise, but I liked the idea of condition objects
carrying the context of the error. A condition is similar to an
exception in some ways except it carries contextual data about the error
and it isn't necessarily exceptional/fatal if not handled. This
particular characteristic of condition objects appeal to me for PHP
because it would allow us to migrate everything to conditions, not just
the fatal errors, without breaking everything.The second part of the Lisp approach is the restart. If you choose to
handle the condition you can also choose to try to gracefully recover by
passing the condition object which includes the context of the error to
an appropriate restart function that lives closer to the code that
actually caused the error. This split allows you to have catch-all type
of condition handlers without losing the ability to do context-aware
error recovery.I would love to see a proposal from someone who understands
condition-restart systems inside out for how they might be applied to PHP.
Thanks Rasmus ... I think that wraps the current state of affairs up nice and
succinctly. Certainly the 'inconsistent' level of exception states are part of
the problem here and why personally I'd rather loose them than add more ...
try/catch always seems like 'I can't be bothered so just do this if you can'
where it would be much tidier if file_put_contents()
; was written so it simply
finished with an error if it has a problem?
--
Lester Caine - G8HFL
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
2012/9/3 Lester Caine lester@lsces.co.uk:
more ... try/catch always seems like 'I can't be bothered so just do this if
you can' where it would be much tidier iffile_put_contents()
; was written
so it simply finished with an error if it has a problem?
Hm. I want to bring in some thoughts.
Perhaps I have not the right words to describe what I mean, but there
are 3 things which come in my mind when PHP may switch the
error-handling to any kind of exceptions:
- Current error-handling has it's advantages. Ideal for short
programs. I don't wanna miss it. I need to ignore errors completely. - I think - prove me wrong :) - it is not possible to change the hole
error-handling from one PHP-version to another, especially when the
behavior changes so entirely. I think it will take some time. Maybe we
have to live with a mixture (new exceptions and old error-handling)
for some time? - Why not having this as concept? Maybe it's a good strategy to
enable both: current error-handling and having exceptions?
The rest is logic: When I want to enable to handle an exception like
an PHP-error, I need to tell PHP during the creation of the error,
that it should not handle it like an exception.
Ok, ok, as Rasmus correctly mentioned, uncaught exceptions are by
definition fatal.
But isn't catching an exception not like "I know how to handle it?"
And when I know how to handle it, couldn't I handle it in the
exception directly?
More questions than answers so far.
--
Alex Aulbach
Hi all,
There's been a lot of discussion around whether or not to include
exceptions for core (no class implementations) errors or not. There's been
a lot said on both sides. However, I'd like to pose the question from a
different angle.Right now, I see the biggest problem with errors currently in PHP is that
there's no easy way of discerning between error types to be able to handle
them. Therefore it's easier to ignore the error than it is to handle it
bluntly. For example, I may want to distinguish between failure modes of
file_put_contents()
. Right now, three types of errors can occur: File not
writable (can't open it), Can't write to file (write failed), and Partial
write only (but certain bytes were written).
http://lxr.php.net/xref/PHP_5_4/ext/standard/file.c#661 Right now, there's
no way short of parsing the error string to even attempt to distinguish
between them (arguably the first two could be treated the same, but the
third could lead to very dangerous situations). Which is non-trivial to say
the least...So, while I know there's some discontent about having the core raise
exceptions, let me ask the question differently:Without moving to exceptions, how could the current error and error
I don't have a good sulotion.
but I definitely dis-agree of throwing exception anywhere..
People like me, like PHP is because it's simple, liking C .
if you throw exception anywhere, then it will be a nightmare for me..
I don't care about what exact error happned, in most cases it runs
well, if it failed, I can go to error log to find out why.
but:
try {
file_put_contents()
;
} catch () {
}
try {
file_put_contents()
;
} catch () {
}
try {
file_put_contents()
;
} catch () {
}
.....
-1
thanks
handling mechanisms be improved to make the scenario I posted above easier.
To make handling errors just as easy as ignoring them (or preferably
easier)...?Thoughts?
Anthony
--
Laruence Xinchen Hui
http://www.laruence.com/