在API中抛出异常的正确时间是什么时候



我正在为我的宠物软件构建一个API,我处于以下情况:

使用其他服务的服务。我有一个服务使用另一个服务来加载程序集,我应该在加载程序集的服务中抛出异常还是在使用该服务的服务上抛出异常?

装配服务:

    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);可以抛出ArgumentNullExceptionArgumentExceptionFileNotFoundExceptionFileLoadExceptionBadImageFormatException。我应该处理所有这些例外情况吗?

UnknownCommandException(commandName) is a custom exception.

另一个问题:任何使用我的API的人都可以知道一个方法何时可以抛出异常?我看到将鼠标放在.Net Framework的任何方法上,您会看到该方法是否会引发异常。这能和我的API方法一起工作吗?

您的标题是抛出异常,但实际上您似乎在谈论捕获异常。通常不应该捕获异常,除非您能够首先纠正导致抛出异常的条件,并且在这种情况下,您应该只捕获可以处理的显式异常类型。

这里需要考虑两件事:

  1. 应用程序的正常流程会突然停止到不再工作的地步吗?例外情况正是这样——发生了异常情况(异常、异常等)的通知。如果不是异常,就不要抛出异常。如果用户可以在没有注意到的情况下继续使用程序,则不要使用异常。

  2. 如何对方法声明进行注释将对此产生影响。注释应该有一些标记标记,允许您解释将抛出什么异常以及在什么情况下抛出。它们看起来像这样:

    /// <exception cref="ExceptionTypeGoesHere"></exception>
    

我通常会尽量避免使用异常来控制程序的流程。程序使用异常将其转换为结果变量,然后将其转换回异常。为什么不一直坚持例外呢?我会更改如下:

    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);
        }                       
    }
}
顾名思义,

api是应用程序的网关。如果api中发生错误,那么告诉消费者错误发生的原因、地点和时间(即api抛出异常)是最有用的。这取决于消费者来捕捉并告诉用户该做什么,或者如果业务逻辑定义良好,消费者将计算替代执行路径。这是我的经验法则

在上面的示例中,程序集加载服务应该抛出错误。如果你在api中处理这个问题,那么消费者永远不会知道:)

有关异常处理的一般指南,请参阅Msdn

最新更新