Чи можна спіймати виняток, який ви не можете обробити (в C #)?

У мене є загальний клас, який ловить виключення з T:

    public abstract class ErrorHandlingOperationInterceptor : OperationInterceptor where T : ApiException
    {
        private readonly Func _resultFactory;

        protected ErrorHandlingOperationInterceptor(Func resultFactory)
        {
            _resultFactory = resultFactory;
        }

        public override Func> RewriteOperation(Func> operationBuilder)
        {
            return() =>
            {
                try
                {
                    return operationBuilder();
                }
                catch (T ex)
                {
                    var operationResult = _resultFactory();
                    operationResult.ResponseResource = new ApiErrorResource { Exception = ex };
                    return operationResult.AsOutput();
                }
            };
        }
    }

З підкласами для конкретних винятків, наприклад

    public class BadRequestOperationInterceptor : ErrorHandlingOperationInterceptor
    {
        public BadRequestOperationInterceptor() : base(() => new OperationResult.BadRequest()) { }
    }

Все це, здається, чудово працює. Але, якось, в журналах (один раз, а не кожен раз) є InvalidCastException:

System.InvalidCastException: Unable to cast object of type 'ErrorHandling.Exceptions.ApiException' to type 'ErrorHandling.Exceptions.UnexpectedInternalServerErrorException'.
   at OperationModel.Interceptors.ErrorHandlingOperationInterceptor`1.c__DisplayClass2.b__1() in c:\BuildAgent\work\da77ba20595a9d4\src\OperationModel\Interceptors\ErrorHandlingOperationInterceptor.cs:line 28

Рядок 28 - це вилов.

Що мені не вистачає? Чи я зробив щось дійсно тупу?

6
Ну, завжди є TruthException , тому що ви не можете впоратися з цим
додано Автор Kieren Johnstone, джерело
@KierenJohnstone, ви викрали мій коментар !!
додано Автор Doug Chamberlain, джерело
Це тому, що виключення, яке виконується, не є типом ApiErrorResource? Який тип колись був схоплений?
додано Автор Smithy, джерело
Я думаю, може бути, тому що T - це особливе виключення, але ви намагаєтеся передати це класу (не в спадщину). Чи можете ви просто ловити всі моменти, а потім дослідити далі? - Просто тому, що операціяBuilder() видає виключення типу ApiException, це не означає, що він не може викинути інші види винятків.
додано Автор Smithy, джерело
Яка рядок у коді - рядок 28?
додано Автор Dylan Meador, джерело
Під час виконання T повинен бути певним винятком. Отже, як це може пройти виключення типу T, але потім не викинути його до T?
додано Автор grahamrhay, джерело
Рядок 28: вилов (T ex)
додано Автор grahamrhay, джерело
Ідея полягала в тому, щоб мати вкладені перехоплювачі, кожен з яких цікавиться лише певним винятком. Якщо б не вдалося це справити, воно блукало.
додано Автор grahamrhay, джерело

1 Відповіді

Як каже кузня, ваш T має тип ApiErrorResource . Ви, десь у своєму коді, намагаєтесь створити свій ErrorHandlingOperationInterceptor з Exception , який НЕ похідний від ApiErrorResource .

try
{
// throw Exception of some sort
}
catch (BadRequestException ex)
{
    BadRequestOperationInterceptor broi = new BadRequestOperationInterceptor ();
}
catch (Exception ex)
{
   //this is NOT right
    BadRequestOperationInterceptor broi = new BadRequestOperationInterceptor ();
}
3
додано
Я думаю, я повинен був сказати "десь, де ELSE в вашому коді".
додано Автор Erik Philips, джерело
Фактично я вважаю, що це тип ApiException .
додано Автор TrueWill, джерело
Я не розумію, як це відповідає на питання. Система типу не повинна дозволяти проблему, яку я думаю, що ви намагаєтеся продемонструвати - зверніть увагу на загальне обмеження , де T: ApiException . Код OP не виконує жодного процесу - як може отримати результат InvalidCastException ?
додано Автор default.kramer, джерело
var chat = new Chat();
var chat = new Chat();
642 учасників

Обсуждение вопросов по C# / .NET / .NET Core / .NET Standard / Azure Сообщества-организаторы: — @itkpi — @dncuug