处理异常:控制器应该返回什么?

时间:2015-10-30 07:21:24

标签: c# exception-handling asp.net-web-api2

我有一个Web API 2控制器操作,它返回一个用户列表

public List<User> GetAll()
{
    try
    {
        return _businessLogic.GetAll();
    }
    catch (Exception ex)
    {
        ExceptionHelper.HandleException(ex, _logger, ControllerContext);
    }
}

class ExceptionHelper {
    public static void HandleException(Exception ex, ILogger _logger, HttpControllerContext controllerContext) {
        _logger.LogError(ex);
        // If possible handle the exception here
        // Code for handling

        // Throw it again
        throw new HttpResponseException(
            controllerContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, errorMessagError)
        );
    }
}

C#编译器抱怨并非GetAll()中的所有代码路径都返回一个值。 问题是,我不想在发生异常时返回任何内容,因为HandleException将记录错误并再次抛出异常。我如何明确表示我不想退货。

3 个答案:

答案 0 :(得分:1)

作为一项规则,您应该处理异常,如果您知道,如何处理异常,以及在处理异常后您想要获得什么。由于异常是关于损坏的状态,您可以恢复状态,或者不应该处理异常。

对于上面的示例,要采用的方法是删除异常处理。那就是:

public List<User> GetAll()
{
    return _businessLogic.GetAll();
}

GetAll方法可能出现的问题:

  • 无法访问的数据源(基础架构问题);
  • 无效的查询/ EF模型/ etc(代码问题)。

无论如何,这些都非常适合HTTP 500“内部服务器错误”,因为这实际上是服务器错误。越早得到用户的反馈,你就越早解决它们。

通常的做法是记录异常。 Web API允许您通过注入自己的IExceptionLogger实现以自定义方式执行此操作:

    public static void Register(HttpConfiguration config)
    {
        // ...
        // ApiNLogLogger is a custom logger, that uses NLog
        config.Services.Add(typeof(IExceptionLogger), new ApiNLogLogger());
    }

答案 1 :(得分:0)

我们知道HandleException会再次抛出异常,但编译器不知道这一点。因此,为了满足编译器验证,无需更改太多代码,您只需在catch块中添加throw;即可。虽然此throw;将无法访问,但编译器验证将通过,您的功能将按预期工作。示例如下:

public List<User> GetAll()
{
    try
    {
        return _businessLogic.GetAll();
    }
    catch (Exception ex)
    {
        ExceptionHelper.HandleException(ex, _logger, ControllerContext);
        throw;//Added throw to remove compilation error.
    }
}

class ExceptionHelper {
    public static void HandleException(Exception ex, ILogger _logger, HttpControllerContext controllerContext) {
        _logger.LogError(ex);
        // If possible handle the exception here
        // Code for handling

        // Throw it again
        throw new HttpResponseException(
            controllerContext.Request.CreateErrorResponse(HttpStatusCode.InternalServerError, errorMessagError)
        );
    }
}

答案 2 :(得分:-1)

以这种方式试试

public List<User> GetAll()
{
    List<User> result = new List<User>();
    try
    {
        result _businessLogic.GetAll();
    }
    catch (Exception ex)
    {
        ExceptionHelper.HandleException(ex, _logger, ControllerContext);
    }
    return result;
}

一个切入点。一个出口点。我个人更喜欢返回空列表,发生一些不好的事情,而不是返回null。