我有一个存储库,当它的EntityNotFoundException
方法无法在数据库中找到所请求的实体时会抛出GetSingle<T>(int id)
。当我在AutoMapper中使用它并发生异常时,我会得到类似的东西:
AutoMapperMappingException:尝试将CategoryDTO映射到类别... ---&gt;
AutoMapperMappingException:尝试将System.Int32映射到CategoryType ... ---&gt;
AutoMapper.MappingException:尝试将System.Int32映射到CategoryType ... ---&gt;
EntityNotFoundException:在数据库中找不到ID为5的类型的实体
我的自定义异常是4级。这使得很难使用try-catch块,因为现在我必须做这样的事情:
try
{
// do the mapping
}
catch (AutoMapperMappingException e)
{
// get the inner-most exception
while (e.InnerException != null)
{
e = e.InnerException;
}
// check to see if it's an EntityNotFoundException
if (e.GetType() == typeof (EntityNotFoundException))
{
var notFound = e as EntityNotFoundException;
// do something specific here, like inform the user
}
else
{
// do something more generic
}
我希望能做的就是:
try
{
// do the mapping
}
catch (EntityNotFoundException e)
{
// do something specific here, like inform the user
}
catch (Exception e)
{
// do something more generic
}
是否有任何方法可以禁用AutoMapper的异常包装行为,以便获得正在抛出的直接异常?
我最终创建了一个围绕AutoMapper
的瘦包装器,它将捕获AutoMapperMappingException
,找到最内层的异常,并抛出它:
public class AutoMapperWrapper
{
public TB Map<TA, TB>(TA source, TB destination)
{
// try to do the mapping
try
{
return Mapper.Map(source, destination);
}
// catch AutoMapper's exception
catch (Exception e)
{
// find the first InnerException that's not wrapped
while (e is AutoMapperMappingException)
{
e = e.InnerException;
}
// if the inner exception is null, throw the original exception
if (e == null)
{
throw;
}
// otherwise, throw the inner exception
else
{
throw e;
}
}
}
}
这种方法的缺点是,有时整个异常树对于查看AutoMapper的哪个属性或实体映射失败很有用,但是这段代码只会给你最内部的异常,有时不是很本身很有用,比如InvalidCastException
:“无法将字符串转换为int”,但不会告诉你它属于哪个属性。