【问题标题】:Propagate exception message from service to controller .NET将异常消息从服务传播到控制器 .NET
【发布时间】:2021-06-22 09:41:13
【问题描述】:

我有一个 .NET 应用程序,其中有一个用于接收用户请求的控制器,一个服务 Service 1 调用另一个服务 Service 2。 我在Service 2 中有一些代码,我在其中查询数据库(DynamoDB)并在用户请求值不正确时得到 500 错误响应。我想处理这个问题,以便我捕捉到这个错误/异常并将错误消息与 400 状态代码一起从控制器发送回用户。我应该如何修改代码来做到这一点?

这是我尝试过的。目前,我只是在Service 1 中打印错误,但我需要将其发送给控制器。通过沿途抛出异常将错误消息发送到控制器是否正确?

以下代码与实际代码类似

控制器:

    [HttpGet]
    [Authorize(Policy = "Read-Entity")]
    [Route("byParams/{param1}/{param2}")]
    [Produces(typeof(DynamoResult<EntityResponse>))]
    public async Task<IActionResult> ListByParams([FromQuery] DynamoQuery entityQuery)
    {
        try
        {
            return await HandleRequest(async () =>
            {
                return Ok((await _entityStore.ListByParams(entityQuery)));
            });
        }
        catch (Exception e)
        {
            return BadRequest(e.Message);
        }
    }

服务 1:

public async Task<DynamoResult<EntityResponse>> ListByParams(DynamoQuery entityQuery)
{            
    results = new DynamoResult<Entity>();
    try {
        results = await GetPagedQueryResults(entityQuery);
    }
    catch (Exception e) {
        Console.WriteLine(e);             
    }
    return new DynamoResult<EntityResponse>
    {
        Data = results.Data.Select(_mapper.Map<EntityResponse>).ToList(),                
    };        
}

服务 2:

private async Task<DynamoResult<TResponse>> GetPagedQueryResults(DynamoQuery query)
{
    var results = new List<Document>();
    try{
        results = await search.GetNextSetAsync();
    }        
    catch(Exception e){
        throw new PaginationTokenException(e.Message);
    }
    return results;
}

[Serializable]
public class PaginationTokenException : Exception
{
    public PaginationTokenException() { }

    public PaginationTokenException(string message)
        : base(message) { 
            throw new Exception(message);
        }

    public PaginationTokenException(string message, Exception inner)
        : base(message, inner) { }
}

【问题讨论】:

    标签: c# .net error-handling amazon-dynamodb


    【解决方案1】:

    假设您想对控制器隐藏实现细节(即您不希望控制器知道/关心它是 DynamoDB),我将创建一个自定义异常并从 Service1 抛出该异常。

    Service1 看起来像这样:

    public async Task<DynamoResult<EntityResponse>> ListByParams(DynamoQuery entityQuery)
    {            
        results = new DynamoResult<Entity>();
        try {
            results = await GetPagedQueryResults(entityQuery);
        }
        catch (Exception e) {
            throw new MyCustomException('My error message', e);             
        }
        return new DynamoResult<EntityResponse>
        {
            Data = results.Data.Select(_mapper.Map<EntityResponse>).ToList(),                
        };        
    }
    

    然后,您可以在控制器中显式捕获该异常:

        [HttpGet]
        [Authorize(Policy = "Read-Entity")]
        [Route("byParams/{param1}/{param2}")]
        [Produces(typeof(DynamoResult<EntityResponse>))]
        public async Task<IActionResult> ListByParams([FromQuery] DynamoQuery entityQuery)
        {
            try
            {
                return await HandleRequest(async () =>
                {
                    return Ok((await _entityStore.ListByParams(entityQuery)));
                });
            }
            catch (MyCustomException e)
            {
                return BadRequest(e.Message);
            }
        }
    

    【讨论】:

    • 好吧,我实现了您的解决方案,并且控件到达了 Service 1 中 catch 块的 throw 语句,但我再次得到相同的 500 响应。我不认为例外是前往控制器。你将如何实现MyCustomException 的构造函数?我是否需要在我正在使用的 PaginationTokenException 异常处理程序中的构造函数中添加任何内容?
    • 你已经明确检查你是否到达了你的控制器中的catch块?
    • @Ralf 我已经检查过了。它没有到达控制器中的 catch 块。
    • 那么我们可以推测HandleRequest方法捕获了异常并返回一些东西而不是传播异常。您可能会查看 HandleRequest 或将异常处理放入给 HandleRequest 的委托中,而不是围绕该调用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-09
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-20
    相关资源
    最近更新 更多