更好的错误处理[重复]

2023-11-23

Here https://github.com/astaxie/build-web-application-with-golang/blob/master/en/11.1.md描述了如何根据 http 包使用自定义路由器和自定义错误类型来增强错误处理。

type appError struct {
    Error   error
    Message string
    Code    int
}    

type appHandler func(http.ResponseWriter, *http.Request) *appError
// custom handler catching errors
func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if e := fn(w, r); e != nil { // e is *appError, not os.Error.
        c := appengine.NewContext(r)
        c.Errorf("%v", e.Error)
        http.Error(w, e.Message, e.Code)
    }
}
// fetch data or return *appError
func viewRecord(w http.ResponseWriter, r *http.Request) *appError {
    c := appengine.NewContext(r)
    key := datastore.NewKey(c, "Record", r.FormValue("id"), 0, nil)
    record := new(Record)
    if err := datastore.Get(c, key, record); err != nil {
        return &appError{err, "Record not found", 404}
    }
    if err := viewTemplate.Execute(w, record); err != nil {
        return &appError{err, "Can't display record", 500}
    }
    return nil
}

目的是让所有处理程序在发生错误时返回 *appError 并将其写入路由器中的响应中,因此无需在代码中直接调用 c.JSON(500, err)viewRecord.

如何做同样的事情Gin?


Here@manucorporat gin-developer 说:

我们鼓励开发人员使用中间件来处理错误响应,这样他们就可以将错误逻辑与正常流程逻辑分开。

在 Gin 中要实现集中错误处理,您应该 .Use(Middleware) 并在路径处理程序的代码中使用 gin.Context.Error() 将错误信息附加到请求上下文。中间件知道 gin.Context.Errors,在这里您可以阅读它们并在之后按照您的意愿进行处理gin.Context.Next().

下面的代码。

错误处理 Gin 中间件:

//
// APP error definition
//
type appError struct {
    Code     int    `json:"code"`
    Message  string `json:"message"`
}

//
// Middleware Error Handler in server package
//
func JSONAppErrorReporter() gin.HandlerFunc {
    return jsonAppErrorReporterT(gin.ErrorTypeAny)
}

func jsonAppErrorReporterT(errType gin.ErrorType) gin.HandlerFunc {
    return func(c *gin.Context) {
        c.Next()
        detectedErrors := c.Errors.ByType(errType)

        log.Println("Handle APP error")
        if len(detectedErrors) > 0 {
            err := detectedErrors[0].Err
            var parsedError *appError
            switch err.(type) {
            case *appError:
                parsedError = err.(*appError )
            default:
                parsedError = &appError{ 
                  code: http.StatusInternalServerError,
                  message: "Internal Server Error"
                }
            }
            // Put the error into response
            c.IndentedJSON(parsedError.Code, parsedError)
            c.Abort()
            // or c.AbortWithStatusJSON(parsedError.Code, parsedError)
            return
        }

    }
}

//
//  Report Error in app
//
func fetchSingleHostGroup(c *gin.Context) {
    hostgroupID := c.Param("id")

    hostGroupRes, err := getHostGroupResource(hostgroupID)

    if err != nil {
        // put the Error to gin.Context.Errors
        c.Error(err)
        return
    }
    // return data of OK
    c.JSON(http.StatusOK, *hostGroupRes)
}
//
// Server setup
//
func main() {
    router := gin.Default()
    router.Use(JSONAppErrorReporter())
    router.GET("/hostgroups/:id", fetchSingleHostGroup)
    router.Run(":3000")
}

另一个错误处理思路可以在:

  • gin-gonic 问题“问题:处理错误”
  • gin-gonic 问题“问题:错误处理中的状态代码”
  • chirp
  • 杜松子酒错误处理程序
  • 杜松子酒 frsh 显示错误
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

更好的错误处理[重复] 的相关文章

  • 如何在 Golang 中将 []byte XML 转换为 JSON 输出

    有没有办法在 Golang 中将 XML byte 转换为 JSON 输出 我有以下功能body is byte但我想在一些操作之后将此 XML 响应转换为 JSON 我试过了Unmarshal in xml打包没有成功 POST func
  • 有没有办法使用 Eclipse 调试 Web 应用程序?

    我正在使用 Eclipse Java IDE 开发 Web 应用程序 我使用 Tomcat 6 作为我的 servlet 容器 可用于 Java 的工具 包括 Eclipse 似乎缺乏 Web 应用程序的调试功能 与 NET 平台的 Vis
  • 由于浏览器设置的标头,Safari 拒绝重定向的 CORS 请求

    Summary Safari 拒绝一些涉及重定向的 CORS 请求 声称某些标头是不允许的 但该标头从来不是由脚本请求的 而是由浏览器添加的 所以我认为这应该不重要 Safari 的行为是一个错误吗 规格有问题吗 或者 事情变成这样是有原因
  • Gorm 总是返回带有 nil 值的结构

    我正在使用 Gorm 构建 Go Web API 作为 Amazon RDS 中 Postgresql 数据库的 ORM 问题是 Gorm 总是返回一片结构 其值全部为零 尽管数据库已经填充了数据 切片中的结构体数量是否合适取决于LIMIT
  • 捕获另一个进程未处理的异常

    我想知道我是否可以捕获我开始使用 Process Start 的另一个进程抛出的未处理的异常 我知道我可以用这个捕获标准错误link http social msdn microsoft com Forums en US csharpgen
  • 响应 301 永久移动

    我曾经得到以下对 php 请求的响应 回复
  • HTTP代理服务器

    我开始研究一个用 C 编写的非常基本的 HTTP 代理服务器 Edit 只是转发我的请求的东西 此时我很难理解如何继续 任何帮助都会有益的 看一眼micro proxy http acme com software micro proxy
  • HTTPWebResponse 响应字符串被截断

    应用程序正在与 REST 服务通信 Fiddler 显示作为 Apps 响应传入的完整良好 XML 响应 该应用程序位于法属波利尼西亚 在新西兰也有一个相同的副本 因此主要嫌疑人似乎在编码 但我们已经检查过 但空手而归 查看流读取器的输出字
  • 我应该避免在 golang 中使用单例包吗?

    现在我有一个包裹store包含以下内容 package store var db Database func Open url string error open db connection func FindAll model inter
  • 根据值匹配数组

    我使用以下代码来解析 yaml 并应得到输出为runners对象和函数build应更改数据结构并根据以下结构提供输出 type Exec struct NameVal string Executer string 这是我尝试过的 但我不知道
  • 如何使用系统凭据自动登录网站?

    我需要为 Intranet 用户开发一个 Web 应用程序 我不希望他们每次访问该网站时都输入登录凭据 它应该从系统用户名和密码自动加载 即 如果他们拥有有效的系统用户名和密码 他们应该能够登录应用程序 我正在使用Java 如何满足这个要求
  • 多少次函数调用会导致堆栈溢出

    你好 Android Java 开发者 当一个函数调用一个函数并且该函数调用另一个函数等等时 有多少次调用 堆栈长度 会让我陷入堆栈溢出 有一般经验法则吗 我问的原因是因为我现在对于我的 5 人纸牌游戏来说哪个更有效 设计明智 解决方案一
  • 如何在android中创建nanohttpd服务器?

    其实我也查过一些问题 然后去github上找了一下 但我是新来的 我无法理解这个例子 我想在android中创建http服务器 这样我就可以在PC浏览器中访问它 我有一个类扩展 nanohttpd 的实例 但服务器无法工作 不知道为什么 我
  • GORM中的一对多递归关系

    我需要有一个Organization与父级有关系 像这样的事情 type Organization struct gorm Model Parent Organization gorm ForeignKey ParentId Name st
  • 使用 Gorilla 会话自定义后端有什么优势?

    我想使用 Redis 进行会话管理 但我不明白使用 Redis 作为 Gorilla 会话包的自定义后端比直接使用它有什么优势 Gorilla 会话包的链接 http www gorillatoolkit org pkg sessions
  • 如何在 PHP 中使用 file_get_contents 获取图像的 MIME 类型

    我需要获取图像的 MIME 类型 但我只有图像的正文file get contents 是否有可能获取 MIME 类型 是的 你可以这样得到它 file info new finfo FILEINFO MIME TYPE mime type
  • 如何确定给定方法可以抛出哪些异常?

    我的问题和这个真的一样 找出 C 中方法可能抛出的异常 https stackoverflow com questions 264747 finding out what exceptions a method might throw in
  • 将自定义数据包含到 iOS 故障转储中

    你好 堆栈溢出 有一个简单的问题要问您 当我的应用程序在用户的设备上崩溃时 是否可以将自定义错误数据嵌入到自动生成的 iOS 故障转储中 例如 我的 SQlite 数据库由于某种原因无法运行 例如 数据库文件已损坏 我无法从这个错误中恢复
  • 正确的 HTTP 重定向状态代码是什么?

    我在我的网站上实现了友好的 URL 我可以通过 URL 以两种方式访问 产品和类别 http www example com home electronics tablets http www example com home electr
  • 如何在 Laravel 中使用 PUT http 动词提交表单

    我知道这个问题可能已经提出 但我就是无法让它发挥作用 如果有人可以帮助我 我将非常感激 我安装了 colletive form 但答案也可以是 html 表单标签 现在列出我的表格 我的路线和我的例外情况 Form model array

随机推荐

  • hyperledger Fabric - 如何删除对等点上的链码?

    我安装了两个chaincode在对等点上 basic network master bin peer chaincode list installed 2018 06 25 10 37 44 825 CST msp GetLocalMSP
  • 基于颜色python的物体边界框

    我尝试在这张图片中的每个对象上绘制一个边界框 我写了这段代码文档 import cv2 as cv2 import os import numpy as np img cv2 imread 1 2 png img cv2 cvtColor
  • GetTickCount() 是否包括暂停或休眠的时间?

    为了澄清 我的意思是花在system被挂起 休眠 而不是调用线程 GetTickCount 返回自系统启动以来的毫秒数 据我所知 GetTickCount与线程无关 它统计系统启动以来的时间 但最好使用获取TickCount64以避免 49
  • InstallShield Basic MSI 项目通过命令行 IsCmdBld.exe 生成新的 GUID

    我有一个 Installshield 项目 ism 我希望能够通过命令行运行它 有一种可能的方法可以通过 CommadnLine 使用 IsCmdBld exe 生成新的产品代码 注意 不能使用其他构建软件 提前致谢 正如 Steve 提到
  • 哪些Android Fragment生命周期方法需要super

    目前 Android API 17 唯一提到的是super在安卓中片段参考是随意通过一些代码示例 不像Android活动参考 它仔细地记录了哪里super是必须的 所以建议搜索网络根据需要 或等待崩溃 以确定调用的位置super是必须的 我
  • 将熊猫切割后的垃圾箱分类

    使用熊猫cut我可以通过提供边缘来定义垃圾箱 并且 pandas 创建垃圾箱 例如 a b 我的问题是如何对垃圾箱进行排序 从最低到最高 import numpy as np import pandas as pd y pd Series
  • IE9 中缩小后的图像质量较差

    我注意到 IE9 以非常低的质量渲染缩小尺寸的图像 如果我在 200x150 IMG 标签中显示 800x600 jpg 图像 则 IE9 中的结果非常令人失望 同一页面在 IE8 和 Chrome 中显示完美 IE7也可以 只要我用CSS
  • linq where 列表包含列表中的任何内容

    使用 linq 如何检索其属性列表与另一个列表匹配的项目列表 以这个简单的例子和 伪代码为例 List
  • :app:assembleRelease 和 assembleRelease 之间的区别

    我的 android 项目中有多个模块 如果我制作一个发行版APK app assembleRelease它可以工作 但是当我用以下命令发布 apk 时assembleRelease它一直显示错误 我知道我的代码中有错误 但这不是我要质疑的
  • 为什么 Haskell 中不需要工厂模式? OOP 中的模式解决的需求在 Haskell 中是如何解决的?

    我读了这个问题有关抽象工厂模式 但唯一的答案是尝试emulate在 Haskell 中就像在 OOP 语言中一样 尽管前言是这样的在 Haskell 中你不需要它 另一方面 我的目的并不是要在像 Haskell 这样的函数式语言上强制采用特
  • 如何在youtube embed api中监听seek事件

    您好 我正在使用 youtube iframe 嵌入 API 我想跟踪用户的搜索视频事件 请帮助我如何跟踪这个 没有简单的方法可以单独使用 api 来跟踪事件 你可以做的是间隔运行一个javascript函数并检查测量的时间差是否与预期的不
  • Rails 可选 /:locale 路线

    我正在尝试为我的 Rails 应用程序设置一个路由系统 该系统允许将可选路由 locale 允许到网站的底部 所以或多或少 en home 将转到与 home 相同的页面 en people gt people 我遇到的唯一问题是在路由配置
  • GoogleCertificatesRslt:Kotlin Android 应用程序中不允许

    我正在开发一个使用 Kotlin 作为开发语言的 Android 应用程序 该应用程序显示地图并应该加载标记 但是 地图会加载 但标记不会加载 我收到安全异常GoogleCertificatesRslt not allowed我发现这可能是
  • 检测前景窗口何时发生变化

    我知道哪个使用GetForegroundWindow函数我可以获取当前活动窗口句柄 但是现在i want to detect when the active window of any application changes become
  • QTabWidget 大小取决于当前选项卡

    I ve a QTabWidget 其中包含不同高度的小部件 它们的宽度是固定的 但是 默认实现QTabWidget选择最大的部件的高度作为自己的高度 我想知道是否有一种 可能快速 的方法来改变大小QTabWidget取决于其当前选项卡 以
  • 删除 Activity 作为默认启动器

    我将我的活动设置为默认启动器来拦截主页按钮点击 如下所示
  • AngularJS 中的滚动事件

    我有一个带有滚动条的 div 现在我想获取一个事件 每次用户滚动时都会触发该事件 这在 AngularJS 中可能吗 还是我必须使用 jQuery Edit 到目前为止我想出了以下内容 JS directive scroll functio
  • 没有名为“fbprophet”的模块?

    我尝试按照以下说明在 Ubuntu 上的 Anaconda 中安装 Facebook Prophet https facebook github io prophet docs installation html installation
  • pip 和 conda 之间的实际区别

    我看到了有关 pip 和 conda 之间差异的其他问题 但我还不清楚 请在标记为重复之前考虑这一点 如果我跑pip install seaborn and conda install seaborn我会得到同样的结果吗 我可以跑pip i
  • 更好的错误处理[重复]

    这个问题在这里已经有答案了 Here https github com astaxie build web application with golang blob master en 11 1 md描述了如何根据 http 包使用自定义路