分享
  1. 首页
  2. 文章

golang用panic和recover做业务流程中断的尝试

陈杰斌 · · 2660 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

随着使用golang越来越频繁,发现golang有一个地方非常不方便,就是在错误处理方面。先来看看golang中通常的错误处理方法:

通常的error处理

package main
import (
	"errors"
	"fmt"
)
func a() (err error) {
	err = errors.New("错误")
	return
}
func main() {
	err := a()
	if err != nil {
		fmt.Println(err)
	}
}

函数在返回的时候增加error类型的返回值,如果有错误则赋值给err,在调用函数处对err进行判断,如果不为nil则处理错误。这种方式在嵌套的层少的时候还好办,要是嵌套的层多了那就要一级一级的返回err,显然会很麻烦。如下面的代码:

package main
import (
	"errors"
	"fmt"
)
func a() (err error) {
	err = b()
	if err != nil {
		return
	}
	err = c()
	if err != nil {
		return
	}
	err = errors.New("a内错误")
	return
}
func b() (err error) {
	err = errors.New("b内错误")
	return
}
func c() (err error) {
	err = errors.New("c内错误")
	return
}
func main() {
	err := a()
	if err != nil {
		fmt.Println(err)
	}
}

a函数内调用了b和c函数,调用后都要进行err != nil的判断,如果再来个d方法,e方法,那岂不是非常麻烦。在实际开发的时候,这种多层嵌套也经常存在,比如用户注册功能就要判断很多东西:表单验证是否OK;用户是否已经存在;数据插入是否OK等等。

用panic的尝试

于是我就想有没什么办法更加方便,至少不用调用每个函数都判断下err!=nil,这样就可以省掉三行代码。了解到golang中的panic方法可以直接中断流程,感觉到沿着这个应该能找到解决方法。了解了下panic的详细使用,其实也很简单,就是panic一下,如果需要捕获这个panic的错误,就在外围的方法事先声明recover方法。看下代码:

package main
import (
	"log"
)
func main() {
	defer func() {
		if r := recover(); r != nil {
			log.Printf("Runtime error caught: %v", r)
		}
	}()
	a()
}
func a() {
	panic("a内错误")
}

a函数内抛出了错误,被外围事先defer的函数recover到,接着就能对错误进行处理了。用这样的方式来改造上面用err处理的代码看看。

package main
import (
	"log"
)
func a() {
	b()
	c()
	panic("a内错误")
	return
}
func b() {
	panic("b内错误")
}
func c() (err error) {
	panic("c内错误")
}
func main() {
	defer func() {
		if r := recover(); r != nil {
			log.Printf("Runtime error caught: %v", r)
		}
	}()
	a()
}

可以看到整个代码都简洁了很多,当然这里的代码比较简单可能看不出什么太大效果,在业务较为繁杂、经常要做各种校验的时候就可以显现出简洁了。

在开发api接口项目的时候,我会封装好recover的方法用来处理内部返回的错误信息,然后统一输出到客户端,感觉便捷很多。


有疑问加站长微信联系(非本文作者)

本文来自:快乐编程

感谢作者:陈杰斌

查看原文:golang用panic和recover做业务流程中断的尝试

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
2660 次点击
1 回复 | 直到 2000年01月01日 00:00:00
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏