-
Notifications
You must be signed in to change notification settings - Fork 850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Modernize exceptions #709
Modernize exceptions #709
Conversation
b6b25a9
to
67264eb
Compare
1731bda
to
255eb01
Compare
4f73f6d
to
82297a6
Compare
r? @brandur-stripe @remi-stripe Fixes #605. Alright, I think this is ready to review. Sorry this is so hard to review, I should have done separate commits :/ I would recommend looking at the new classes in Also cc @nickdnk and @Nek-, curious if you have any feedback! |
I think this is a fine solution. On your last point left unchecked: In my opinion it should definitely not inherit from While this thread is a question about Java, its answers outline the reasoning behind checked/unchecked (runtime) exceptions and when and why they are useful (and when they are not): https://stackoverflow.com/questions/6115896/understanding-checked-vs-unchecked-exceptions-in-java. Since we're interacting with an API far away and outside our control as users of the library, it makes very much sense to force us to always take into consideration that Stripe may return an error - even in cases we expect it not to. We should always recover gracefully from this. Using That's my take on it anyway. I know checked vs. unchecked is somewhat of a religion, but hey, I believe checked exceptions are a good thing when used properly. Some other libraries that use https://github.com/facebook/php-graph-sdk |
LGTM OB. A cleanup of epic proportions! I might be missing something due to general PHP ignorance, but one question I had was around the UX of Put another way, having an |
Perhaps this thread can enlighten us: guzzle/guzzle#2184 - we may end up creating a situation with problems similar to what developers experience with this Guzzle interface. I'd recommend that we have all exceptions extend from an abstract class (that extends |
That was basically the way it was implemented before, all exceptions derived from the I think the interface is preferable because it lets us wrap SPL exceptions, which are now used for some client-side errors (previously we used Right now the stuff common to all API errors is implemented by the |
But was that a problem? I don't think this implementation solves any of the problems we had with the |
82297a6
to
7ba41b7
Compare
I think having a different inheritance tree on errors that are caused by programming errors is a good approach, such as throwing an |
I just wanted to say as well that IMO it'd also be fine to leave the trait, but just duplicate a lot of its properties onto |
We can't do that because |
Ah, I see! Okay, that sounds good too though. |
94f3f46
to
fcff210
Compare
Okay, I made a few changes:
I'm fairly happy with the result except for one thing: we have |
@ob-stripe I think renaming it to |
Cool, that's my preference too. I'll go ahead and make that change. (Also thanks for all your help and feedback here, much appreciated!) |
You're welcome. I'm also a little confused about the purpose of |
Just to clarify; #605 is not solved by these changes, as we'll still get the warnings that all the actual exceptions are "not thrown" (as phpdocs only mention the abstract base class). I don't think that can be solved without explicitly adding all possible API errors to all methods - which I'm well aware you understandingly don't want to do. |
I'm no PHP expert but I saw this pattern being employed by a lot of PHP codebases (https://www.google.com/search?q=exceptioninterface.php+site%3Agit.luolix.top). My understanding is that it serves as a nice way to know whether an exception was thrown by a library or by your own code, as long as the library makes sure that all exceptions it throws implement its interface (which I believe I've done here).
Yes, sorry, I should have said that it "partially" solves the issue. Previously I had annotated the methods with |
That does make sense. Let's stick with that.
I like only being forced to handle errors that come from the Stripe API, so I think this solution is probably the best middle-ground, with the problem still being that if you catch something like |
2973d9a
to
96e7a5e
Compare
5c2a2fa
to
5a02d12
Compare
4e522ca
to
a87cf6a
Compare
a87cf6a
to
5082dee
Compare
Okay, I think I've made all the changes we wanted. I've also updated the first post with the current state of the PR. ptal @brandur-stripe |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the broad changes Olivier. LGTM!
Thanks Brandur and Nick! |
This is a large PR that is kind of hard to review -- sorry!
\Stripe\Error
namespace to\Stripe\Exception
Exception
suffixExceptionInterface
interface implemented by all our exception classesBase
/OAuthBase
abstract classes toApiErrorException
/OAuthErrorException
factory
method to create instancesBadMethodCallException
,InvalidArgumentException
andUnexpectedValueException
that wrap the matching SPL exceptions (the purpose of these wrappers is to add theExceptionInterface
interface, so users can catch any and all exceptions raised within stripe-php by catching\Stripe\Exception\ExceptionInterface
)Api
toUnknownApiErrorException
UnknownOAuthErrorException
All the above changes make the exceptions much more idiomatic and less surprising for PHP developers. Defining an
ExceptionInterface
implemented by all exceptions in the codebase (including standard SPL exceptions by defining wrapper classes) is standard practice for modern PHP codebases.