У меня есть хранилище, которое выдает EntityNotFoundException
, когда его GetSingle<T>(int id)
метод не может найти запрошенную сущность в базе данных.Когда я использую это с AutoMapper и возникает исключение, я получаю что-то вроде этого:
AutoMapperMappingException: при попытке сопоставить CategoryDTO с Category ... --->
AutoMapperMappingException:Попытка сопоставить System.Int32 с CategoryType ... --->
AutoMapper.MappingException: Попытка сопоставить System.Int32 с CategoryType ... --->
EntityNotFoundException: сущностьТип CategoryType с идентификатором 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», но не сообщит вам, какиесобственности это было.