Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.
https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
Pierrick
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
Pierrick
Hi!
It may be an issue that this is close in design to [0] union types.
This RFC would be great for code quality, just might be a subset of
union types.
thanks
Hi all,
It may be an issue that this is close in design to [0] union types.
This RFC would be great for code quality, just might be a subset of
union types.thanks
Nice and handy!
If we are going to support this kind of code, union types seem better way.
However, I have mixed feeling..
Current PHP has issues like string literal/string type/__toStringed
object are treated differently. For instance,
http://www.phpwtf.org/instanceof-smart
I would like to sort out and fix these kind of issues first. i.e. Let
array type Traversable
Just my .02
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Hi Sean and Yasuo
I agree that they are somehow related, but I also think (and I might be
wrong) that the behaviour of the Multi-Catch is obvious and I don't see how
this syntax/feature could be interpreted otherwise. The multi-catch don't
have any open-issue that the Union-Types have like weak types since it only
deals with Exceptions. Also, we still don't know if we'll one day have the
Union-Types since there are those open issues and it would be sad to wait
something that could never append. It's IMO pretty safe going forward and
if required in the future change the implementation when needed (Behaviour
will stay the same, unless you see other behaviour that this syntax could
have in this same "catch" context).
Pierrick
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
PierrickHi!
It may be an issue that this is close in design to [0] union types.
This RFC would be great for code quality, just might be a subset of
union types.thanks
Den 2016-03-08 kl. 22:42, skrev Pierrick Charron:
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
Pierrick
Nice RFC! Think it would be good if you had an example in the
RFC showing the applicability of catching two php exceptions.
Especially given the new exception hierarchy in PHP 7. I'm also
pondering if the main target for this is custom exceptions or
the built-in ones or both?
Regards //Björn Larsson
PS
Hi Björn,
The only time I had to do this with core PHP exceptions is to make the code
compatible for both PHP5 and PHP7:
try {
} catch(\Exceptions $e) {
} catch(\Throwable $e) {
}
But it will of course not be applicable since this feature is targeting
PHP7.1. Other than that the PHP core exception hierarchy is well enough for
MY needs. But if someone already had to do this fill free to provide your
use case as an example.
My main target is custom exceptions (even if the logic is applicable on
everything Throwable). A custom exception use case would be some method
that throw thwo different kind of exceptions like for example the doctrine
AbstractQuery::getSingleResult (NoResultException,
NonUniqueResultException) that you could want to handle the same way.
An other really easy example would be simple code like this one that I
found in symfony (not really a big deal but still)
} catch (AccessException $e) {
return false;
} catch (UnexpectedTypeException $e) {
return false;
}
And other piece of code using multiple libraries.
Den 2016-03-08 kl. 22:42, skrev Pierrick Charron:
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
PierrickNice RFC! Think it would be good if you had an example in the
RFC showing the applicability of catching two php exceptions.
Especially given the new exception hierarchy in PHP 7. I'm also
pondering if the main target for this is custom exceptions or
the built-in ones or both?Regards //Björn Larsson
PS
Hi :)
I think it is feature that is useful time to time, not very often.
One example:
class PackingFailed extends \Exception implements PackagingException {}
// this exception could originate from package with assertions/exceptions,
// so I cannot use common interface with above
class EmptyName extends \Exception implements ValidationException {}
class Packer
{
/** @throws PackingFailed */
public function pack(PackTemplate $packTemplate) : Pack
{
try {
return $this->save($packTemplate);
} catch (IOException $e) {
throw new PackingFailed('', 0, $e);
}
}
}
class PackTemplate
{
/** @throws EmptyName */
public function __construct(string $name)
{
if ($name === '') {
throw new EmptyName();
}
}
}
/** @throws SomeException */
function packeForMe(string $name) : Pack
{
try {
return (new Packer())->pack(new PackTemplate($name));
} catch (PackingFailed | ValidationException $e) {
throw new SomeException($e); // or return null in other cases
}
}
2016-03-09 2:47 GMT+01:00 Pierrick Charron pierrick@adoy.net:
Hi Björn,
The only time I had to do this with core PHP exceptions is to make the
code compatible for both PHP5 and PHP7:try {
} catch(\Exceptions $e) {
} catch(\Throwable $e) {
}But it will of course not be applicable since this feature is targeting
PHP7.1. Other than that the PHP core exception hierarchy is well enough for
MY needs. But if someone already had to do this fill free to provide your
use case as an example.My main target is custom exceptions (even if the logic is applicable on
everything Throwable). A custom exception use case would be some method
that throw thwo different kind of exceptions like for example the doctrine
AbstractQuery::getSingleResult (NoResultException,
NonUniqueResultException) that you could want to handle the same way.An other really easy example would be simple code like this one that I
found in symfony (not really a big deal but still)} catch (AccessException $e) {
return false;
} catch (UnexpectedTypeException $e) {
return false;
}And other piece of code using multiple libraries.
Den 2016-03-08 kl. 22:42, skrev Pierrick Charron:
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
PierrickNice RFC! Think it would be good if you had an example in the
RFC showing the applicability of catching two php exceptions.
Especially given the new exception hierarchy in PHP 7. I'm also
pondering if the main target for this is custom exceptions or
the built-in ones or both?Regards //Björn Larsson
PS
--
Pozdrawiam,
Bronisław Białek.
Hi, Thanks for clarifying. Think the RFC would benefit from having
some of these examples in it. I also had in mind that it's handy for
catching many exceptions when logging stuff and re-throwing like:
} catch (FirstException | SecondException ex) {
logger.error(ex);
throw ex;
}
Regards //Björn
PS Sorry for top-posting...
Den 2016-03-09 kl. 08:05, skrev Bronisław Białek:
Hi :)
I think it is feature that is useful time to time, not very often.
One example:class PackingFailed extends \Exception implements PackagingException {}
// this exception could originate from package with assertions/exceptions,
// so I cannot use common interface with above
class EmptyName extends \Exception implements ValidationException {}class Packer
{
/** @throws PackingFailed */
public function pack(PackTemplate $packTemplate) : Pack
{
try {
return $this->save($packTemplate);
} catch (IOException $e) {
throw new PackingFailed('', 0, $e);
}
}
}class PackTemplate
{
/** @throws EmptyName */
public function __construct(string $name)
{
if ($name === '') {
throw new EmptyName();
}
}
}/** @throws SomeException */
function packeForMe(string $name) : Pack
{
try {
return (new Packer())->pack(new PackTemplate($name));
} catch (PackingFailed | ValidationException $e) {
throw new SomeException($e); // or return null in other cases
}
}2016-03-09 2:47 GMT+01:00 Pierrick Charron pierrick@adoy.net:
Hi Björn,
The only time I had to do this with core PHP exceptions is to make the
code compatible for both PHP5 and PHP7:try {
} catch(\Exceptions $e) {
} catch(\Throwable $e) {
}But it will of course not be applicable since this feature is targeting
PHP7.1. Other than that the PHP core exception hierarchy is well enough for
MY needs. But if someone already had to do this fill free to provide your
use case as an example.My main target is custom exceptions (even if the logic is applicable on
everything Throwable). A custom exception use case would be some method
that throw thwo different kind of exceptions like for example the doctrine
AbstractQuery::getSingleResult (NoResultException,
NonUniqueResultException) that you could want to handle the same way.An other really easy example would be simple code like this one that I
found in symfony (not really a big deal but still)} catch (AccessException $e) {
return false;
} catch (UnexpectedTypeException $e) {
return false;
}And other piece of code using multiple libraries.
Den 2016-03-08 kl. 22:42, skrev Pierrick Charron:
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
PierrickNice RFC! Think it would be good if you had an example in the
RFC showing the applicability of catching two php exceptions.
Especially given the new exception hierarchy in PHP 7. I'm also
pondering if the main target for this is custom exceptions or
the built-in ones or both?Regards //Björn Larsson
PS
Thanks for your feedback !
Any other thoughts from anyone else on this ?
Hi, Thanks for clarifying. Think the RFC would benefit from having
some of these examples in it. I also had in mind that it's handy for
catching many exceptions when logging stuff and re-throwing like:} catch (FirstException | SecondException ex) {
logger.error(ex);
throw ex;
}Regards //Björn
PS Sorry for top-posting...
Den 2016-03-09 kl. 08:05, skrev Bronisław Białek:
Hi :)
I think it is feature that is useful time to time, not very often.
One example:class PackingFailed extends \Exception implements PackagingException {}
// this exception could originate from package with assertions/exceptions,
// so I cannot use common interface with above
class EmptyName extends \Exception implements ValidationException {}class Packer
{
/** @throws PackingFailed */
public function pack(PackTemplate $packTemplate) : Pack
{
try {
return $this->save($packTemplate);
} catch (IOException $e) {
throw new PackingFailed('', 0, $e);
}
}
}class PackTemplate
{
/** @throws EmptyName */
public function __construct(string $name)
{
if ($name === '') {
throw new EmptyName();
}
}
}/** @throws SomeException */
function packeForMe(string $name) : Pack
{
try {
return (new Packer())->pack(new PackTemplate($name));
} catch (PackingFailed | ValidationException $e) {
throw new SomeException($e); // or return null in other cases
}
}2016-03-09 2:47 GMT+01:00 Pierrick Charron pierrick@adoy.net:
Hi Björn,
The only time I had to do this with core PHP exceptions is to make the
code compatible for both PHP5 and PHP7:try {
} catch(\Exceptions $e) {
} catch(\Throwable $e) {
}But it will of course not be applicable since this feature is targeting
PHP7.1. Other than that the PHP core exception hierarchy is well enough
for
MY needs. But if someone already had to do this fill free to provide your
use case as an example.My main target is custom exceptions (even if the logic is applicable on
everything Throwable). A custom exception use case would be some method
that throw thwo different kind of exceptions like for example the
doctrine
AbstractQuery::getSingleResult (NoResultException,
NonUniqueResultException) that you could want to handle the same way.An other really easy example would be simple code like this one that I
found in symfony (not really a big deal but still)} catch (AccessException $e) {
return false;
} catch (UnexpectedTypeException $e) {
return false;
}And other piece of code using multiple libraries.
On 8 March 2016 at 18:06, Björn Larsson bjorn.x.larsson@telia.com
wrote:Den 2016-03-08 kl. 22:42, skrev Pierrick Charron:
Hi internals,
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.https://wiki.php.net/rfc/multiple-catch
A working implementation and tests are available in the RFC.
We are waiting for your constructive feedback and thoughts.
Thanks
PierrickNice RFC! Think it would be good if you had an example in the
RFC showing the applicability of catching two php exceptions.
Especially given the new exception hierarchy in PHP 7. I'm also
pondering if the main target for this is custom exceptions or
the built-in ones or both?Regards //Björn Larsson
PS
Hi!
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.
Would it not be better, to have your Exceptions extend a common base
class in this case? Or perhaps, which I think is even better, to have
your Exception classes implement a common interface that you can catch
against. That I believe should already work.
What you are asking PHP users to do with a multiple catch like this, is
to test in each catch's statement block to test for each class again.
Neither the inheritence or implements options from the previous
paragraph have that issue.
cheers,
Derick
2016-03-09 12:52 GMT+01:00 Derick Rethans derick@php.net:
Hi!
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.Would it not be better, to have your Exceptions extend a common base
class in this case? Or perhaps, which I think is even better, to have
your Exception classes implement a common interface that you can catch
against. That I believe should already work.
This assumes they're my exceptions and I can change the code. Doesn't work
with libraries having not that good exception structures or even leaking
their dependency's exceptions.
What you are asking PHP users to do with a multiple catch like this, is
to test in each catch's statement block to test for each class again.
No, usually it's enough that they're all extending Exception / Throwable.
You just can't catch Exception / Throwable, because that would catch all
exceptions. If you have a multi-catch, it doesn't matter which exception is
thrown and it's never checked, otherwise you'd use two blocks directly.
Regards, Niklas
Neither the inheritence or implements options from the previous
paragraph have that issue.cheers,
Derick
Hi Derick
I agree that most of the time the best solution is to implement a clean
exception hierarchy but as stated in the RFC :
"A solution to fix this problem on the user level would be to implement a
common interface for ExceptionType1 and ExceptionType2 and catch it.
However, this is only possible when you control the exception hierarchy in
your own code, but not possible when you don't control the code."
Hi!
Bronisław Białek and I would like to start a discussion about allowing
multiple exception types to be caught in a single catch statement.Would it not be better, to have your Exceptions extend a common base
class in this case? Or perhaps, which I think is even better, to have
your Exception classes implement a common interface that you can catch
against. That I believe should already work.What you are asking PHP users to do with a multiple catch like this, is
to test in each catch's statement block to test for each class again.
Neither the inheritence or implements options from the previous
paragraph have that issue.cheers,
Derick
Hi Derick
I agree that most of the time the best solution is to implement a clean
exception hierarchy but as stated in the RFC :"A solution to fix this problem on the user level would be to implement a
common interface for ExceptionType1 and ExceptionType2 and catch it.
However, this is only possible when you control the exception hierarchy in
your own code, but not possible when you don't control the code."
I understand the use-case, but I don't see it as a widespread scenario. In
most cases, I've been doing something like following:
public function stuff()
{
try {
$this->willFail();
} catch (FirstException $e) {
$this->handleFailure($e);
} catch (SecondException $e) {
$this->handleFailure($e);
} catch (ThirdException $e) {
$this->handleFailure($e);
}
}
Even then, this is a rare eventuality, and as pointed out above, usually
fixed when wrapping exceptions correctly, if you have control over the
exception types).
Seems way below the 80/20 use-case to me, and introduces syntax changes as
well.
Cheers,
Marco Pivetta
Hi Derick
I agree that most of the time the best solution is to implement a clean
exception hierarchy but as stated in the RFC :"A solution to fix this problem on the user level would be to implement a
common interface for ExceptionType1 and ExceptionType2 and catch it.
However, this is only possible when you control the exception hierarchy in
your own code, but not possible when you don't control the code."I understand the use-case, but I don't see it as a widespread scenario. In
most cases, I've been doing something like following:
I agree that this the RFC will not get the oscar for feature of the year,
but I think it will lead in those few use-case to more readable code.
public function stuff()
{
try {
$this->willFail();
} catch (FirstException $e) {
$this->handleFailure($e);
} catch (SecondException $e) {
$this->handleFailure($e);
} catch (ThirdException $e) {
$this->handleFailure($e);
}
}
The thing I don't like about this approach is that I have to read the code
and double check to make sure that the catch statement call the same method.
For the amount of work that needs to be done in the Engine (see the patch
attached to the RFC) this is far more readable and it is clear that the
code to handle those 3 exceptions is the exact same one. And if the code of
handleFailure is small you can even put it at this single place.
public function stuff()
{
try {
$this->willFail();
} catch (FirstException | SecondException | ThirdException $e) {
$this->handleFailure($e);
}
}
Even then, this is a rare eventuality, and as pointed out above, usually
fixed when wrapping exceptions correctly, if you have control over the
exception types).
Seems way below the 80/20 use-case to me, and introduces syntax changes as
well.Cheers,
Marco Pivetta
I'm definetly lately started to use instanceof to check the type of
exception I've got and throw further those that I don't need. This is
especially valuable for CLI applications (I have a few daemons in PHP).
So a big +1 on the proposal idea, as for the tech part - maybe unions is a
good idea.
Arvids Godjuks.
Hi Derick
I agree that most of the time the best solution is to implement a clean
exception hierarchy but as stated in the RFC :"A solution to fix this problem on the user level would be to implement
a
common interface for ExceptionType1 and ExceptionType2 and catch it.
However, this is only possible when you control the exception hierarchy
in
your own code, but not possible when you don't control the code."I understand the use-case, but I don't see it as a widespread scenario.
In
most cases, I've been doing something like following:I agree that this the RFC will not get the oscar for feature of the year,
but I think it will lead in those few use-case to more readable code.public function stuff()
{
try {
$this->willFail();
} catch (FirstException $e) {
$this->handleFailure($e);
} catch (SecondException $e) {
$this->handleFailure($e);
} catch (ThirdException $e) {
$this->handleFailure($e);
}
}The thing I don't like about this approach is that I have to read the code
and double check to make sure that the catch statement call the same
method.
For the amount of work that needs to be done in the Engine (see the patch
attached to the RFC) this is far more readable and it is clear that the
code to handle those 3 exceptions is the exact same one. And if the code of
handleFailure is small you can even put it at this single place.public function stuff()
{
try {
$this->willFail();
} catch (FirstException | SecondException | ThirdException $e) {
$this->handleFailure($e);
}
}Even then, this is a rare eventuality, and as pointed out above, usually
fixed when wrapping exceptions correctly, if you have control over the
exception types).
Seems way below the 80/20 use-case to me, and introduces syntax changes
as
well.Cheers,
Marco Pivetta
The thing I don't like about this approach is that I have to read the code
and double check to make sure that the catch statement call the same method.
For the amount of work that needs to be done in the Engine (see the patch
attached to the RFC) this is far more readable and it is clear that the
code to handle those 3 exceptions is the exact same one. And if the code of
handleFailure is small you can even put it at this single place.public function stuff()
{
try {
$this->willFail();
} catch (FirstException | SecondException | ThirdException $e) {
$this->handleFailure($e);
}
}
I'd still have to write 3 test cases anyway: no real amount of code-savings
there.
I still think the first solution is as readable as the one you proposed
there.
The change in the PHP engine might be trivial, but the syntax change from a
userland perspective is a mess (tooling, pretty much anything that relies
on an AST parser needs changes there).
Do not underestimate language changes as a php-core only issue.
Marco Pivetta
The thing I don't like about this approach is that I have to read the
code and double check to make sure that the catch statement call the same
method.
For the amount of work that needs to be done in the Engine (see the patch
attached to the RFC) this is far more readable and it is clear that the
code to handle those 3 exceptions is the exact same one. And if the code of
handleFailure is small you can even put it at this single place.public function stuff()
{
try {
$this->willFail();
} catch (FirstException | SecondException | ThirdException $e) {
$this->handleFailure($e);
}
}I'd still have to write 3 test cases anyway: no real amount of
code-savings there.
Agree
I still think the first solution is as readable as the one you proposed
there.
Agree to disagree ;-)
The change in the PHP engine might be trivial, but the syntax change from
a userland perspective is a mess (tooling, pretty much anything that relies
on an AST parser needs changes there).
Do not underestimate language changes as a php-core only issue.
You're right but I think those impact should not prevent us to make the
language evolve even for small changes that are just like this one
syntactic sugar. With the amount of user doing PHP code on a daily basis
those changes are IMO worth it.
Marco Pivetta
Hi,
Le mer. 9 mars 2016 à 14:08, Marco Pivetta ocramius@gmail.com a écrit :
Hi Derick
I agree that most of the time the best solution is to implement a clean
exception hierarchy but as stated in the RFC :"A solution to fix this problem on the user level would be to implement a
common interface for ExceptionType1 and ExceptionType2 and catch it.
However, this is only possible when you control the exception hierarchy
in
your own code, but not possible when you don't control the code."I understand the use-case, but I don't see it as a widespread scenario. In
most cases, I've been doing something like following:public function stuff()
{
try {
$this->willFail();
} catch (FirstException $e) {
$this->handleFailure($e);
} catch (SecondException $e) {
$this->handleFailure($e);
} catch (ThirdException $e) {
$this->handleFailure($e);
}
}Even then, this is a rare eventuality, and as pointed out above, usually
fixed when wrapping exceptions correctly, if you have control over the
exception types).
Seems way below the 80/20 use-case to me, and introduces syntax changes as
well.
+1
I will add to this that Exceptions must remain... exceptional! Too much
projects relies already on tens or hundreds of business exception while
those are mostly common "error" conditions that are better handled with
dedicated API calls.
To me, it doesn't look like a reasonable change when we consider the number
of tools/IDE to adapt compared to the possible usage of it.
Cheers,
Patrick
Thanks for the feedback Patrick :-) I understand your concern. I added a
section to the RFC Impact section to mention that PHP tools/IDE will
require some modifications. Feel free to add some additional details in
this section if you want. People who will vote will then be aware of the
situation and I'll of course comply to the voters decision :-)
Pierrick
Hi,
Le mer. 9 mars 2016 à 14:08, Marco Pivetta ocramius@gmail.com a écrit :
Hi Derick
I agree that most of the time the best solution is to implement a clean
exception hierarchy but as stated in the RFC :"A solution to fix this problem on the user level would be to implement
a
common interface for ExceptionType1 and ExceptionType2 and catch it.
However, this is only possible when you control the exception hierarchy
in
your own code, but not possible when you don't control the code."I understand the use-case, but I don't see it as a widespread scenario. In
most cases, I've been doing something like following:public function stuff()
{
try {
$this->willFail();
} catch (FirstException $e) {
$this->handleFailure($e);
} catch (SecondException $e) {
$this->handleFailure($e);
} catch (ThirdException $e) {
$this->handleFailure($e);
}
}Even then, this is a rare eventuality, and as pointed out above, usually
fixed when wrapping exceptions correctly, if you have control over the
exception types).
Seems way below the 80/20 use-case to me, and introduces syntax changes as
well.+1
I will add to this that Exceptions must remain... exceptional! Too much
projects relies already on tens or hundreds of business exception while
those are mostly common "error" conditions that are better handled with
dedicated API calls.To me, it doesn't look like a reasonable change when we consider the
number of tools/IDE to adapt compared to the possible usage of it.Cheers,
Patrick