Способ обработки исключения, вызванного действием, переданным в качестве параметра функции - PullRequest
0 голосов
/ 11 ноября 2019
  try
    {
        if (productDto.Images != null)
        {
            productDto.ImagesUrls = new List<string>();
            foreach (var image in productDto.Images)
            {
                var name = await _imageWriter.UploadImage(image);
                productDto.ImagesUrls.Add(name);
            }

            await _repository.RemoveProductImages(productDto.Id);
            await _repository.SetNewImagesPathsForProduct(productDto.Id, productDto.ImagesUrls);
        }

        var result =  await base.UpdateAsync(productDto, commands, async (ProductDto dto, bool name) =>
                await CustomValidationWithUserRole(productDto, true));
        return result;
    }
    catch (Exception ex)
    {
        foreach (var imagePath in productDto.ImagesUrls)
            await _imageWriter.RemoveFile(imagePath);

        var oldImageUrls = productDto.ImagesUrls;

        await _repository.SetNewImagesPathsForProduct(productFromDb.Id, oldImageUrls);

        throw;
    }

Согласно фрагменту кода, я передаю функцию, которая возвращает void, но она может выдать исключение, если одно из свойств модели недопустимо или какой-либо сущности не существует в db (проверка).

Проблема возникает, когда этот метод (CustomValidationWithUserRole) генерирует исключение. Он не пойман в этом операторе try-catch.

Как я могу перехватить это исключение и передать его дальше контроллеру (который находится на один уровень выше)?

Ниже приведены места, где явызываю эту функцию:

    public async Task<UDto> UpdateAsync(UDto dto, List<Command> commands = null, Action<UDto, bool> customDtoEntityValidation = null)
    {
        var updatedModel = default(TModel);

        try
        {
            await DtoSingleValidate(dto, customDtoEntityValidation, true);
            var model = await ConvertDtoToModel(dto);
            updatedModel = await _repository.UpdateAsync(model);
            var updatedDto = await ConvertModelToDto(updatedModel);

            SetIds(commands, updatedDto);
            await SendCommands(commands);
            return updatedDto;
        }
        catch (Exception ex)
        {
            if (updatedModel != default(TModel))
            {
                await _repository.DeleteAsync(updatedModel);
            }
            throw;
        }
    }

    private async Task DtoSingleValidate(UDto dto, Action<UDto, bool> customDtoEntityValidation, bool update)
    {
        if (customDtoEntityValidation == null)
        {
            await DtoValidation(dto, update);
        }
        else
        {
            customDtoEntityValidation.Invoke(dto, update);
        }
    }

1 Ответ

2 голосов
/ 11 ноября 2019

Это происходит потому, что Action, который вы передаете, является асинхронным, и ничего не ждет результата. Действие выполняется как огонь и забывается, и нет ничего, чтобы поймать исключение, так как вызывающий объект уже перешел.

Вам необходимо изменить тип customDtoEntityValidation на Func<UDto, bool, Task> и awaitрезультат соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...