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
Bad exception thrown when fake's base's constructor fails #367
Comments
Agreed, that error message is weak. I've recently been plagued by these types of @FakeItEasy/owners, I'd had in mind an idea to catch |
Changing title - was FakeCreationException thrown for abstract member call in constructor. Issues already exist for FIE's deficiencies around overrideable methods being called from constructors (#368, #365), so we'll focus a little more here on the exception message (which may arise from other causes than those in the mentioned issues). |
@matkoch, I think that not exposing the inner exception may have been intentional to create "prettier" error messages, although perhaps only @patrik-hagne can comment on this. When all relevant information is included in the "pretty" message, this is not a bad thing. When the info is missing, it's a detriment. I'm not specifically against including the inner exception, but suspect that unwrapping the |
So what happens currently? We swallow the actual exception and throw a new |
Yes, that. (Almost?) Always. In most cases, we go to (sometimes herculean) efforts to provide a helpful error message. When it works, it's great, since we have very tidy, helpful messages that aren't obscured by giant stacktraces. When it doesn't work, we get errors like above. As I say, I can probably be convinced to include the InnerException, but I think unwrapping the |
Including InnerException is more work than I thought, but unwrapping the
( Do we think this is sufficient? If not, I can continue looking at attaching the inner exception. |
One of the reason that setting the InnerException is tricky is that there may be multiple constructors that have been tried, with multiple of them having thrown exceptions. I guess in that case we could use an InnerException list, but I wonder if it isn't getting too fancy. |
Actually, I think this trying is a code smell. Instead FIE should know in advance, what constructor has to be invoked (e.g., given through passed arguments), but that's a different story. If you have multiple exceptions being thrown during construction, I would definitely expose the related ConstructorInfo with them as a property. You could also put the signature into the message. |
I don't think the trying is a code smell. It's a feature. If you ask FakeItEasy to make a fake something (or a Dummy, but let's leave that aside for now, although it may come back), it will try to make it however it can. Of course if arguments are passed, it will use the constructor whose arguments match. But if no arguments are specified, it will try a parameterless constructor first. If that doesn't work, it will try to use any available constructor, in descending order of parameter list length. I don't follow your second paragraph. We do already indicate the matching signature of failed constructors when there are problems. Consider a failed attempt to fake a class that has only one constructor, with signature
(Ignore the "Exception has been thrown by the target…" stuff. I don't have my "improved" error reporting with me.) You can see that the report indicates that there's no parameterless constructor, and that the "Constructor with signature (System.String, FakeItEasyQuestions.AnotherClass) failed", and why. (Although the "why" could be improved.) |
I'm planning on sending a PR that will have
Although this does not explicitly include an InnerException in the FakeCreationException, I think it satisfies the spirit of the issue and will help users determine what went wrong with their fake creation. I think it also maintains what appears to be FIE's unwritten policy of helpful, comprehensive exception messages when something goes wrong. Any objections? |
@blairconrad your proposal sounds fine. I don't think there's any point trying to engineer a list of inner exceptions. This exception is not designed to be caught, but rather to bubble out to the console so enriching the message appropriately is the right thing to do. If we later discover that people are wanting to use FIE in a more SDK-like manner and actually catch the exception and inspect the inner exceptions then we can revisit but I doubt this will crop up. |
- using FluentAssertions - reformatting some tests - other minor refactorings
- using FluentAssertions - reformatting some tests - other minor refactorings
- using FluentAssertions - reformatting some tests - other minor refactorings
…ncat Per inspection comments in FakeItEasy#381.
#367 - Bad exception thrown when fake's base's constructor fails
@matkoch, thanks very much for your work on this issue. Look for your name in the release notes. 🏆 This issue has been fixed in release 2.0.0. |
Related to #365, FIE throws a
FakeCreationException
when calling a fakable method (with struct return type) in the constructor. However, the current exception message isn't really helpful, because it doesn't outline that possibility.As long as #365 is not solved somehow, FIE should either state this situation in the exception, or, what i prefer, introduce a new exception type for virtual/abstract calls in the constructor. Also, the thrown
FakeCreationException
doesn't expose the inner exception - it is null. I think it could be wrapped.The text was updated successfully, but these errors were encountered: