В какое время нужно создать исключение в API? - PullRequest
2 голосов
/ 23 марта 2012

Я создаю API для своего любимого программного обеспечения и нахожусь в следующей ситуации:

Сервис, который использует другой сервис. У меня есть служба, которая использует другую службу для загрузки сборки. Должен ли я выдать исключение в службу, которая загружает сборку, или в службу, которая использует эту службу?

AssemblyService:

    public class AssemblyService : IAssemblyService
    {
        public Assembly Load(string assemblyName)
        {
            Assembly assembly;

            try
            {
                assembly = Assembly.Load(assemblyName);
            }
            catch
            {
                assembly = null;
            }

            return assembly;
        }

        ...

    }

Сервис, который использует AssemblyService:

    public class CommandService : ICommandService
    {
        private readonly IAssemblyService assemblyService;

        public CommandService(IAssemblyService assemblyService)
        {
            this.assemblyService = assemblyService;
        }

        public CommandOutput Process(string inputCommand, string requestInfo)
        {
            string commandName = GetAssemblyName(inputCommand);
            string args = GetArgs(inputCommand);

            Assembly assembly = assemblyService.Load(commandName);

            if (assembly == null) throw new UnknownCommandException(commandName);

            ICommand command = assemblyService.GetCommand(assembly);

            return command.Execute(args, requestInfo);
        }

        #region Private methods
        ...
        #endregion
    }

Должен ли я генерировать исключение в AssemblyService или CommandService, как в примере выше?

Я пытаюсь научиться обрабатывать исключение, в приведенном выше примере строка assembly = Assembly.Load(assemblyName); может выдать ArgumentNullException, ArgumentException, FileNotFoundException, FileLoadException и BadImageFormatException. Должен ли я обрабатывать все эти исключения?

UnknownCommandException(commandName) is a custom exception.

Другой вопрос: Кто-нибудь, кто использует мой API, может знать, когда метод может вызвать исключение? Я вижу, как навести указатель мыши на любые методы .Net Framework, и вы увидите, может ли метод вызвать исключение. Может ли это работать с методами моего API?

Ответы [ 4 ]

5 голосов
/ 23 марта 2012

Ваш заголовок посвящен выбрасыванию исключений, но на самом деле вы, похоже, говорите о перехвате исключений. Как правило, вы не должны перехватывать исключения, если вы не можете сделать что-то значимое, чтобы исправить условие, которое вызвало исключение, и в этом случае вы должны только перехватывать явные типы исключений, которые вы можете обработать.

2 голосов
/ 23 марта 2012

Здесь нужно подумать о двух вещах:

  1. Будет ли нормальный поток приложения внезапно остановлен до такой степени, что он больше не будет работать?Исключением является именно это - уведомление о том, что произошло что-то исключительное (необычное, ненормальное и т. Д.).Если это не исключение, не бросайте исключение.Если пользователь может продолжать использовать программу, не замечая этого, не используйте исключение.

  2. То, как вы прокомментируете объявление метода, повлияет на это.Должны быть некоторые теги разметки для комментариев, которые позволят вам объяснить, какое исключение будет сгенерировано и при каких обстоятельствах оно будет сгенерировано.Они выглядят так:

    /// <exception cref="ExceptionTypeGoesHere"></exception>
    
1 голос
/ 23 марта 2012

Обычно я стараюсь избегать использования исключений для управления потоком программы.Ваша программа использует исключение для преобразования его в переменную результата, а затем преобразует его обратно в исключение.Почему бы не придерживаться исключений полностью?Я бы изменил это следующим образом:

    public class AssemblyService : IAssemblyService
{
    public Assembly Load(string assemblyName)
    {
        return Assembly.Load(assemblyName);         
    }
}

public class CommandService : ICommandService
{
    private readonly IAssemblyService assemblyService;

    public CommandService(IAssemblyService assemblyService)
    {
        this.assemblyService = assemblyService;
    }

    public CommandOutput Process(string inputCommand, string requestInfo)
    {           
        string commandName = GetAssemblyName(inputCommand);

        try
        {
            string args = GetArgs(inputCommand);

            Assembly assembly = assemblyService.Load(commandName);
            ICommand command = assemblyService.GetCommand(assembly);
            return command.Execute(args, requestInfo);
        }
        catch (Exception ex)
        {
            //Log original exception or add to inner exception
            throw new UnknownCommandException(commandName);
        }                       
    }
}
1 голос
/ 23 марта 2012

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

в приведенном выше примере служба загрузки сборки должна выдать ошибку.Если вы справитесь с этим в API, то потребитель никогда не узнает:)

общие рекомендации по обработке исключений, смотрите здесь в Msdn

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