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