我正在使用gin编写一个简单的REST API。我已经阅读了许多有关使出错处理在go中不再重复的文章和文章,但是我似乎无法全神贯注于如何在gin处理程序中进行错误处理。
我所做的所有工作就是对数据库运行一些查询,并将结果返回为JSON,因此典型的处理程序如下所示
func DeleteAPI(c *gin.Context) {
var db = c.MustGet("db").(*sql.DB)
query := "DELETE FROM table WHERE some condition"
tx, err := db.Begin()
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
defer tx.Rollback()
result, err := tx.Exec(query)
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
num, err := result.RowsAffected()
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
err = tx.Commit()
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"deleted": num})
}
Run Code Online (Sandbox Code Playgroud)
如您所见,即使这个简单的处理程序也会重复执行相同的“ if err!= nil”模式四次。在基于“选择”的API中,我有两倍多,因为绑定输入数据时可能存在错误,而将响应编组到JSON时则存在错误。有什么办法可以使它更干吗?
我通常的方法是使用包装函数。这样做的优点是(相对于Adrian的答案,这也是一个不错的选择,顺便说一句),将错误处理保留为Go惯用的形式(of return result, err,而不是用handleError(err)类型调用来填充代码),同时仍将其合并为一个位置。
func DeleteAPI(c *gin.Context) {
num, err := deleteAPI(c)
if err != nil {
c.JSON(400, gin.H{"error": err.Error()})
return
}
c.JSON(200, gin.H{"deleted": num})
}
func deleteAPI(c *gin.Context) (int, error) {
var db = c.MustGet("db").(*sql.DB)
query := "DELETE FROM table WHERE some condition"
tx, err := db.Begin()
if err != nil {
return 0, err
}
defer tx.Rollback()
result, err := tx.Exec(query)
if err != nil {
return 0, err
}
num, err := result.RowsAffected()
if err != nil {
return 0, err
}
err = tx.Commit()
if err != nil {
return 0, err
}
return num, nil
}
Run Code Online (Sandbox Code Playgroud)
对我(通常对Go编码器而言),其优先级是代码可读性高于DRY。在我看来,在这三个选项(您的原始选项,Adrian的选项和我的选项)中,我的版本更具可读性,原因很简单,即错误是完全以惯用的方式处理的,并且它们冒泡到顶级处理程序。如果您的控制器最终调用其他返回错误的函数,则此方法同样有效。通过将所有错误处理移至最顶层的函数,您在所有其余代码中都将摆脱错误处理的混乱(简单的'if err!= nil {return err}`结构除外)。
还值得注意的是,通过更改“包装”函数,此方法可以与Adrian结合使用,特别是与多个处理程序一起使用时,功能强大:
func DeleteAPI(c *gin.Context) {
result, err := deleteAPI(c)
if handleError(c, err) {
return
}
c.JSON(200, gin.H{"deleted": num})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1091 次 |
| 最近记录: |