• 自定义 ocelot 中间件输出自定义错误信息


    自定义 ocelot 中间件输出自定义错误信息

    Intro

    ocelot 中默认的 Response 中间件在出错的时候只会设置 StatusCode 没有具体的信息,想要展示自己定义的错误信息的时候就需要做一些自定义了,对 ocelot 中的 Response 中间件做了一些小改动,实现了输出自定义错误信息的功能。

    Implement

    实现起来其实也很简单,原来的有错误的时候,只设置了 Response 的 StatusCode,我们只需要加一下输出错误信息就可以了,错误信息的格式完全可以自定义,实现代码如下:

    public class CustomResponseMiddleware : Ocelot.Middleware.OcelotMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IHttpResponder _responder;
        private readonly IErrorsToHttpStatusCodeMapper _codeMapper;
    
        public CustomResponseMiddleware(
            RequestDelegate next,
            IHttpResponder responder,
            IErrorsToHttpStatusCodeMapper codeMapper,
            IOcelotLoggerFactory loggerFactory)
            : base(loggerFactory.CreateLogger<UrlBasedAuthenticationMiddleware>())
        {
            _next = next;
            _responder = responder;
            _codeMapper = codeMapper;
        }
    
        public async Task Invoke(HttpContext httpContext)
        {
            await _next.Invoke(httpContext);
            if (httpContext.Response.HasStarted)
                return;
    
            var errors = httpContext.Items.Errors();
            if (errors.Count > 0)
            {
                Logger.LogWarning($"{errors.ToErrorString()} errors found in {MiddlewareName}. Setting error response for request path:{httpContext.Request.Path}, request method: {httpContext.Request.Method}");
    
                var statusCode = _codeMapper.Map(errors);
                var error = string.Join(",", errors.Select(x => x.Message));
                httpContext.Response.StatusCode = statusCode;
                // output error
                await httpContext.Response.WriteAsync(error);
            }
            else
            {
                Logger.LogDebug("no pipeline errors, setting and returning completed response");
    
                var downstreamResponse = httpContext.Items.DownstreamResponse();
    
                await _responder.SetResponseOnHttpContext(httpContext, downstreamResponse);
            }
        }
    }
    

    相比之前的中间件,主要变化就是对于 Error 的处理,感觉这里 ocelot 可以抽象一下,增加一个接口 ErrorResponser 之类的,现在的 responder 没有直接把错误信息直接传进去造成一些不变,加一个 ErrorResponder 只处理 Error 相关的逻辑,把错误信息直接传进去,这样用户也就可以更为灵活的注册自己的服务来无侵入的修改发生错误时的行为

    Sample

    要使用这个中间件,就要自己定义 ocelot 中间件的配置,把默认的 Response 中间件替换成自己的中间件即可,示例如下:

    app.UseOcelot((ocelotBuilder, ocelotConfiguration) =>
    {
        // this sets up the downstream context and gets the config
        app.UseDownstreamContextMiddleware();
        // This is registered to catch any global exceptions that are not handled
        // It also sets the Request Id if anything is set globally
        ocelotBuilder.UseExceptionHandlerMiddleware();
    
        // This is registered first so it can catch any errors and issue an appropriate response
        //ocelotBuilder.UseResponderMiddleware();
        ocelotBuilder.UseMiddleware<CustomResponseMiddleware>();
    
        ocelotBuilder.UseDownstreamRouteFinderMiddleware();
        ocelotBuilder.UseMultiplexingMiddleware();
        ocelotBuilder.UseDownstreamRequestInitialiser();
        ocelotBuilder.UseRequestIdMiddleware();
    
        // 自定义中间件,模拟没有权限的情况
        ocelotBuilder.Use((ctx, next) =>
        {
            ctx.Items.SetError(new UnauthorizedError("No permission"));
            return Task.CompletedTask;
        });
        //ocelotBuilder.UseMiddleware<UrlBasedAuthenticationMiddleware>();
    
        ocelotBuilder.UseLoadBalancingMiddleware();
        ocelotBuilder.UseDownstreamUrlCreatorMiddleware();
        ocelotBuilder.UseHttpRequesterMiddleware();
    }).Wait();
    

    除了上面的 Response 中间件,为了测试方便,我还加了一个中间件,直接设置了一个 Error 来方便测试,随便访问一个 Path 来测试一下是不是会有错误信息,可以看到正如预期的结果一样,输出了我们自定义的错误信息

    More

    完整示例可以从 Github 上获取 https://github.com/WeihanLi/AspNetCorePlayground/tree/master/OcelotDemo

    Reference

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    事务数据oracle 锁1
    编译文件系统移植linux3.0.62 + busybox最小系统到单板TQ2440
    事务说明[tomcat] spring2.5.6 + hiberante3.1.3 + atomikos3.8.0 多数据源事务配置
    字符判断字母顺序问题
    维度字段缓慢渐变维度的处理方式
    nullnull提取汉字第一个字母
    期望连续2013百度之星4.27月赛 题目一 Fir
    覆盖距离AsiaHatyai2012 & LA 6144 Radiation 二分搜索
    冒泡,插入,希尔,快排的比较
    链表打印从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/weihanli/p/14383810.html
Copyright © 2020-2023  润新知