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
AutoMapper catches and ignores NullReferenceException #122
Comments
Could be addressed by allowing custom DelegateBasedResolver |
Yes, is that possible today with 2.0? We had an idea to find a way using alot of reflection magic, but havnt gotten around to it yet. |
I wonder - I could do this only with ResolveUsing and not in MapFrom. Since MapFrom is expression-based, there's a little bit more expectation on not allowing NREs through, but ResolveUsing you're on your own. Would that work? |
FWIW; I've just removed AutoMapper from a project because of this issue. I spent some time wondering why my mapping code was not working correctly. It was a NRE that caused a chunk of mapping to be skipped over, and was not me deliberately wanting to to a.b.c.d without null checks, but a genuine oversight in my code. I don't believe swallowing exceptions (especially NREs) by default is ever an acceptable thing to do. It masks real issues and makes them really difficult to debug (since the consumer of your library probably does not expect this behaviour by default). This should be opt-in as a minimum, but since you can't ever tell which NREs are "convenience" and which are real bugs with mappings, I really don't think you should even have this "feature". It made me chuckle that I found this blog post of yours while Googling to figure out what the problem was: http://lostechies.com/jimmybogard/2007/04/30/swallowing-exceptions-is-hazardous-to-your-health/ I liked AutoMapper; but I just can't bring myself to use software that swallows exceptions without needing to opt-in. I'm not pleading for you to change this; it might be useful behaviour to more people than there are that dislike it; but I thought it was worth you having my thoughts. |
Yikes. |
:-/ I didn't mean for my comment to seem like a rant; I just wanted to document my thoughts/reasoning (constructively, hopefully) should @jbogard wish to consider them for future versions. It would be nice if this functionality was opt-in. It's hard enough working on a huge legacy codebase (with lots of dev and lots of refactoring) without having to sink time into debugging issues because of silent exceptions :( |
I guess what I'm most interested in is your specific scenario. What your On Thursday, August 29, 2013, Danny Tuppeny wrote:
|
I was new'ing up an object in the map with a few properties. One threw NRE which aborts the entire block, so the other properties failed. I don't have the code to hand and I'm on a tablet, but it was something similar to: MapFrom/ResolveUsing(o => new Something(o.a.b.c, o.b.c.d)); If a is null, it doesn't pass null into the constructor (obviously), so the whole Something ends up null, silently. Without knowing what's going on, it was a very strange issue to understand. I might be using this wrong, but with no XML comments explaining this behaviour, it seems way too easy to fall into this trap and lose time scratching your head. |
I think then maybe the resolver is the best way to handle this? Not do NRE MapFrom is a bit different in that it's for redirection, without complex On Thursday, August 29, 2013, Danny Tuppeny wrote:
|
MapFrom should inspect for null, ResolveUsing should not. |
Whatever you do, please a) add XML comments to the methods making it clear where exceptions will be discarded and b) document this somewhere. The reason this is so frustrating is that it's both undocumented (in XML docs and the wiki!) and unexpected :-( |
Wiki is editable by anyone, and I welcome pull requests :) Valid point tho |
Is this not the current behavior? I'm pretty sure it is. |
I don't believe it is. The following code has the NullReferenceException swallowed, whether you use MapFrom or ResolveUsing. I'm running this with the latest stable version from NuGet.
|
I just tested this on 2.2.1 and .ResolveUsing() doesn't throw the exception either, so I don't know what I was thinking. I was checking to see if there was a difference between 2.2.1 and 3.0. |
I think I hit another more subtle issue while doing this too; ResolveUsing(/MapFrom?) expected a function that returned object; and if the returned value doesn't "fit" in the property being mapped, it also seemed to be silently thrown away. IMO that's terrible for the same reason... Unexpected and tricky to track down. |
This issue seems to have cropped back up. The 8.0 Upgrade Guide says to change all |
It's just a rename. The Func based MapFroms are the same code as ResolveUsing. |
Ah, sorry, I see what happened. When reading the docs it seemed like all one had to do was replace |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
As written in:
http://stackoverflow.com/questions/7332426/automapper-catches-and-ignores-nullreferenceexception
Maybe this is by design, but we initially did not expect automapper to catch and ignore all NullReferenceExceptions in our mappings. We mostly use the MapFrom and create sometimes complex expressions. We want these mappings to fail if there's any exception, even a NullReferenceException, but we cant get AutoMapper to do that. Is there any way to make automapper not ignore all these exceptions without having to write a custom value resolver for every case? This would mean alot of extra code for us, so much in fact that it probably would be less code without using automapper in the first place.
These are the test that we would expect to all pass:
[TestFixture]
public class Tests
{
[SetUp]
public void Setup() { Mapper.Reset(); }
}
public class Destination
{
public string DestinationMember { get; set; }
}
public class Source
{
public SourceChild SourceMember { get; set; }
}
public class SourceChild
{
public string SourceProperty { get; set; }
}
public class TestValueResolver : ValueResolver<SourceChild, string>
{
protected override string ResolveCore(SourceChild source)
{
return source.SourceProperty;
}
}
The text was updated successfully, but these errors were encountered: