@Mike,

> Then about a year ago I started using Go, and Go's approach to error
> handling just clicked for me. Go's philosophy is to handle the error as
> soon as you one is aware of it and to only ever handle it once.  Since I
> have been using that strategy I have become very happy with my error
> handling, and I now (attempt) to use the same strategy in my PHP code.
> So what I am hoping for is that PHP recognizes there are two strategies
> for error handling — 1. Throwing exceptions vs. 2. Returning error values —
> and that PHP 8.0 and behind will respect programmers and allow them to
> embrace the strategy they feel is best for their use-case.



I do see some value in the way Go handles errors (i.e. forcing you to deal
with them), especially the *expected* ones; the issue, if I'm not mistaken,
is how you deal with *unexpected* errors. AFAICS, this forces you to either
return it to the caller (which may not expect this error), or wrap it in a
more specific error that's part of your function's contract, which is
pretty much what you do with exception chaining. I don't have a hands-on
experience with Go, though, so I may have missed something. Please do
correct me if/where needed.


@Rowan,


You've backed that up with exactly one example function, and immediately
> concede a case where you might want a non-exception flow. Here are a
> handful more examples off the top of my head:
> * Attempt to atomically lock and open file, returning either a file
> handle or a "could not lock" status.
> * Attempt to read from a file, terminate loop when the file handle
> reaches EOF.
> * Attempt to delete file, ignore if it doesn't exist.
> All of these are candidates for returning false, or an error code, or an
> object in a particular status. They could be handled with exceptions,
> but that would force common patterns to use exceptions for flow control,
> which is generally seen as a "bad smell".



I used this one function as an example, but I'm happy to apply my point of
view to other examples if you wish. I'll take yours above, in reverse order:

*-  Attempt to delete file, ignore if it doesn't exist:*

unlink($file): bool; // true if the file was deleted, false if it didn't
exist; exception on other errors

As I see it, the only safe-to-ignore error is "the file does not exist"
(non-exceptional error), as the outcome is the same whatever the return
value: the file does not exist (anymore).
Any other error should, IMO, be treated as exceptional and throw.

*- Attempt to read from a file, terminate loop when the file handle reaches
EOF:*

I think the current API is already quite good at that, it just needs a bit
of polish in the way it handles errors:

while (! feof($fp)) $block = fread($fp, 4096);

feof($fp): bool; // true if EOF, false if not; exception on error
fread($fp): string; // the data, empty string if EOF (non-exceptional);
exception on error

I don't see much value in doing something like:

for (;;) {
    $result = fread($fp, 4096);
    if ($result->isEOF) break;
    if ($result->error) {
        // ...
    }

    $block  = $result->data;
}

*- Attempt to atomically lock and open file, returning either a file handle
or a "could not lock" status:*

fopen_and_lock($fp); // true if lock was acquired, false if not; exception
on error

This one is trickier, as the outcome is roughly the same (the file was
open) but maybe the lock failed to acquire. I can't say if I would return
bool, or void and an exception on failure-to-acquire.


Don't get me wrong, I respect your points of view, they are perfectly
valid, and as such I'm not trying to push exceptions over anything else;
but I don't personally see them as bad at all, they're actually quite
convenient if used properly. I do see some value in returning errors, too,
but with the strong caveat expressed below, that may severely affect
inexperienced, or, should I say it, lazy developers. I like the exception
model, breaking the program flow by default if unhandled. This makes an app
much more reliable *by default* IMHO.

Therefore I do like the original proposal, even if I can hardly imagine it
overcome the usual resistance here.
This proposal would be as good under the form of a new API though, but in
this case the naming should be changed to clearly differentiate both APIs.

I wish you luck, @David, anyway.

— Benjamin



On Mon, 21 Oct 2019 at 23:59, Rowan Tommins <rowan.coll...@gmail.com> wrote:

> On 21/10/2019 21:38, Benjamin Morel wrote:
> > Sure, you can do without exceptions. I think what you're suggesting is
> > similar to Go's error handling. But PHP at some point decided in
> > favour of exceptions, so it would be logical to pursue in that direction.
>
>
> I didn't say "do without exceptions", I said "use exceptions when
> they're the right tool, and other tools at other times".
>
>
> > I would classify most, if not all, filesystem-related functions as
> > mostly "yes, do stop execution by default when something fails". So
> > this is, as well, in favour of exceptions.
>
>
> You've backed that up with exactly one example function, and immediately
> concede a case where you might want a non-exception flow. Here are a
> handful more examples off the top of my head:
>
> * Attempt to atomically lock and open file, returning either a file
> handle or a "could not lock" status.
> * Attempt to read from a file, terminate loop when the file handle
> reaches EOF.
> * Attempt to delete file, ignore if it doesn't exist.
>
> All of these are candidates for returning false, or an error code, or an
> object in a particular status. They could be handled with exceptions,
> but that would force common patterns to use exceptions for flow control,
> which is generally seen as a "bad smell".
>
>
> > Handling each and every error manually by using the return value
> > requires a lot of discipline, which could be a very steep learning
> > curve for PHP developers used to a fast prototyping language.
>
>
> Again, I am not saying that every function should have a complex
> error-handling system. It may well be sensible to have a function for
> "open file, I don't expect anything to go wrong" which throws an
> exception, and a separate one for "try to open file, and report the
> result without ever triggering an exception". That's the point of
> designing a new API, to work out what the use cases are, and cater for
> them in a clean way.
>
>
> Regards,
>
> --
> Rowan Tommins (né Collins)
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

Reply via email to