捕获异常_Recover捕获异常

de0223b4b5d5cf99acd3321f746fff81.gif

 本文来源于《The Go Programming Language》

5.10. Recover捕获异常

通常来说,不应该对panic异常做任何处理,但有时,也许我们可以从异常中恢复,至少我们可以在程序崩溃前,做一些操作。举个例子,当web服务器遇到不可预料的严重问题时,在崩溃前应该将所有的连接关闭;如果不做任何处理,会使得客户端一直处于等待状态。如果web服务器还在开发阶段,服务器甚至可以将异常信息反馈到客户端,帮助调试。

如果在deferred函数中调用了内置函数recover,并且定义该defer语句的函数发生了panic异常,recover会使程序从panic中恢复,并返回panic value。导致panic异常的函数不会继续运行,但能正常返回。在未发生panic时调用recover,recover会返回nil。

让我们以语言解析器为例,说明recover的使用场景。考虑到语言解析器的复杂性,即使某个语言解析器目前工作正常,也无法肯定它没有漏洞。因此,当某个异常出现时,我们不会选择让解析器崩溃,而是会将panic异常当作普通的解析错误,并附加额外信息提醒用户报告此错误。

func Parse(input string) (s *Syntax, err error) {
defer func() {
if p := recover(); p != nil {
err = fmt.Errorf("internal error: %v", p)
}
}()
// ...parser...
}

deferred函数帮助Parse从panic中恢复。在deferred函数内部,panic value被附加到错误信息中;并用err变量接收错误信息,返回给调用者。我们也可以通过调用runtime.Stack往错误信息中添加完整的堆栈调用信息。

不加区分的恢复所有的panic异常,不是可取的做法;因为在panic之后,无法保证包级变量的状态仍然和我们预期一致。比如,对数据结构的一次重要更新没有被完整完成、文件或者网络连接没有被关闭、获得的锁没有被释放。此外,如果写日志时产生的panic被不加区分的恢复,可能会导致漏洞被忽略。

虽然把对panic的处理都集中在一个包下,有助于简化对复杂和不可以预料问题的处理,但作为被广泛遵守的规范,你不应该试图去恢复其他包引起的panic。公有的API应该将函数的运行失败作为error返回,而不是panic。同样的,你也不应该恢复一个由他人开发的函数引起的panic,比如说调用者传入的回调函数,因为你无法确保这样做是安全的。

有时我们很难完全遵循规范,举个例子,net/http包中提供了一个web服务器,将收到的请求分发给用户提供的处理函数。很显然,我们不能因为某个处理函数引发的panic异常,杀掉整个进程;web服务器遇到处理函数导致的panic时会调用recover,输出堆栈信息,继续运行。这样的做法在实践中很便捷,但也会引起资源泄漏,或是因为recover操作,导致其他问题。

基于以上原因,安全的做法是有选择性的recover。换句话说,只恢复应该被恢复的panic异常,此外,这些异常所占的比例应该尽可能的低。为了标识某个panic是否应该被恢复,我们可以将panic value设置成特殊类型。在recover时对panic value进行检查,如果发现panic value是特殊类型,就将这个panic作为errror处理,如果不是,则按照正常的panic进行处理(在下面的例子中,我们会看到这种方式)。

下面的例子是title函数的变形,如果HTML页面包含多个,该函数会给调用者返回一个错误(error)。在soleTitle内部处理时,如果检测到有多个,会调用panic,阻止函数继续递归,并将特殊类型bailout作为panic的参数。

// soleTitle returns the text of the first non-empty title element
// in doc, and an error if there was not exactly one.
func soleTitle(doc *html.Node) (title string, err error) {
type bailout struct{}
defer func() {
switch p := recover(); p {
case nil: // no panic
case bailout{}: // "expected" panic
err = fmt.Errorf("multiple title elements")
default:
panic(p) // unexpected panic; carry on panicking
}
}()
// Bail out of recursion if we find more than one nonempty title.
forEachNode(doc, func(n *html.Node) {
if n.Type == html.ElementNode && n.Data == "title" &&
n.FirstChild != nil {
if title != "" {
panic(bailout{}) // multiple titleelements
}
title = n.FirstChild.Data
}
}, nil)
if title == "" {
return "", fmt.Errorf("no title element")
}
return title, nil
}

在上例中,deferred函数调用recover,并检查panic value。当panic value是bailout{}类型时,deferred函数生成一个error返回给调用者。当panic value是其他non-nil值时,表示发生了未知的panic异常,deferred函数将调用panic函数并将当前的panic value作为参数传入;此时,等同于recover没有做任何操作。(请注意:在例子中,对可预期的错误采用了panic,这违反了之前的建议,我们在此只是想向读者演示这种机制。)

有些情况下,我们无法恢复。某些致命错误会导致Go在运行时终止程序,如内存不足。

924bd45c707681ef2d43c2a69806cf5b.png- End -6f4520fd471e43f8aa566f3fa58120fc.png

好文点赞收藏

4aa4f2f3f912babf6425bfeacc00e655.png4aa4f2f3f912babf6425bfeacc00e655.png4aa4f2f3f912babf6425bfeacc00e655.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496654.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

仿msn弹出窗口

msnMessage.js文件代码: Code1 /** 2 ** 3 ** 类名:msnMessage 4 ** 功能:提供类似MSN消息框 5 ** 示例: 6 --------------------------------------------------------------------------------…

CPU诞生记|CPU制造全过程详解

来源:电子产品世界CPU(Centralprocessingunit)是现代计算机的核心部件,又称为“微处理器”。对于PC而言,CPU的规格与频率常常被用来作为衡量一台电脑性能强弱重要指标。Intelx86架构已经经历了二十多个年头,而x86架构的CPU对我们大…

二维数组 类型_Java第六章 | 二维数组的创建及使用、数组排序算法

二维数组的创建及使用1、二维数组的创建2、二维数组初始化3、使用二维数组二维数组的创建声明二维数组的方法有两种,语法如下所示:数组元素类型 数组名字[ ][ ];数组元素类型[ ][ ] 数组名字;数组元素类型:决定了数组的数据类型,它…

Semaphore及其用法

1、Semaphore 是什么 Semaphore 通常我们叫它信号量, 可以用来控制同时访问特定资源的线程数量,通过协调各个线程,以保证合理的使用资源。 比如:停车场入口立着的那个显示屏,每有一辆车进入停车场显示屏就会显示剩余…

sklearn 逻辑回归Demo

逻辑回归案例 假设表示 基于上述情况,要使分类器的输出在[0,1]之间,可以采用假设表示的方法。 设 h θ ( x ) g ( θ T x ) h_θ (x)g(θ^T x) hθ​(x)g(θTx), 其中 g ( z ) 1 ( 1 e − z ) g(z)\frac{1}{(1e^{−z} )} g(z)(1e−z)1​…

URL原理、URL编码、URL特殊字符、输入URL到页面显示

​From:http://blog.csdn.net/zmx729618/article/details/51381655 From:http://www.cnblogs.com/coco1s/p/5038412.html HTML URL 编码参考手册:https://www.w3cschool.cn/htmltags/html-urlencode.html http://www.w3school.com.cn/t…

记忆模糊、记忆泛化的关键分子开关被发现

来源:brainnews2018年3月12日,Nature Medicine杂志在线刊登了麻省总医院Amar Sahay研究组的最新重要工作,他们发现了一种细胞骨架蛋白Actin-binding LIM protein 3 (ABLIM3),降低该蛋白的表达水平可以增强海马齿状回细胞&#xff…

240多个jQuery插件 (转)

概述 jQuery 是继 prototype 之后又一个优秀的 Javascript 框架。其宗旨是—写更少的代码,做更多的事情。它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不及的,它兼容 CSS3,还兼容各种浏览器(IE 6.0, FF 1.5, Safari 2.…

Exchanger及其用法

01 Exchanger 作用 使两个线程之间进行数据传递。(对是两个之间而不是三个或者更多个线程之间) 02 常用方法 exchange() 阻塞当前线程并等待其他线程来取得数据,若没有其他线程来取数据则一直等待。 exchange&…

2 如何设置窗口title_如何设置华为4G路由2的WiFi黑白名单【设置方法】

不想让自家的Wi-Fi被蹭网,除了将Wi-Fi隐藏起来,您还可以设置Wi-Fi黑白名单。如果您发现有人蹭网了,可以将蹭网设备直接加入黑名单,这样就可以禁止这个设备再连接到您的Wi-Fi。如果您将家人、朋友的设备加入了白名单,那…

谷歌大脑AutoML最新进展:用进化算法发现神经网络架构

来源:AI中国大脑的进化进程持续已久,从5亿年前的蠕虫大脑到现如今各种现代结构。例如,人类的大脑可以完成各种各样的活动,其中许多活动都是毫不费力的。例如,分辨一个视觉场景中是否包含动物或建筑物对我们来说是微不足…

linux 的 ip 命令 和 ifconfig 命令

From(试试Linux下的ip命令,ifconfig已经过时了): https://linux.cn/article-3144-1.html From(linux网络配置命令之ifconfig、ip和route): http://chrinux.blog.51cto.com/6466723/1188108 From…

对于Office Live平台的思考

刚接触计算机编程的时候,脑子里想法比肚子里的墨水多得多,那时候想通过网络成立一个游戏开发团队,将不少人都很喜欢的一款FC游戏“重装机兵”(Metal Max)移植到电脑上来。当时的想法很激进也很宏大,我想的不…

中国学者用人工光感受器助失明小鼠复明

来源:《自然—通讯》中国研究人员在英国《自然通讯》杂志上发表报告说,他们通过在失明小鼠眼底植入一种新研发的人工光感受器,让它们的视觉得以恢复。如果这种技术发展成熟,未来或许能帮助因黄斑变性等疾病而视力下降或失明的患者…

boundcolumn 根据值进行判断_Excel使用函数进行条件判断的方法步骤

Excel中的函数具体该如何进行判断数据的条件是否达到要求呢?下面是学习关于excel使用函数进行条件判断的教程,希望阅读过后对你有所启发! excel使用函数进行条件判断的教程 函数条件判断步骤1:如何计算成绩是否合格 函数条件判断步骤2:选中要…

城市大脑不仅是AI系统,更是结合人类智慧的混合智能巨系统

作者:刘锋 《互联网进化论》作者从2015年开始,智慧城市的类脑化进程不断加速,包括城市大脑,城市云脑,城市神经系统,智慧城市脑,交通大脑等概念不断涌现,人工智能成为当前科技热点的今…

转载:ListBox的SelectedValue和SelectedItem的区别

转载:ListBox的SelectedValue和SelectedItem的区别 原文:http://www.beacosta.com/blog/?p9What is the difference between SelectedValue and SelectedItem? When they are used by themselves, these two properties are very similar. The need fo…

上帝的指纹——分形与混沌

来源:王东明科学网博客云朵不是球形的,山峦不是锥形的,海岸线不是圆形的,树皮不是光滑的,闪电也不是一条直线。——分形几何学之父Benoit Mandelbrot话说在一个世纪以前,数学领域相继出现了一些数学鬼怪&am…

scrapy 教程

------------------------------------------------------------------------------------------ scrapy 中文文档 和 scrapy 英文文档参照看。因为中文文档比较老,英文文档是最新的。 scrapy 英文文档:https://doc.scrapy.org/en/latest scrapy 中文文档…

智慧停车产业链市场全透析

来源:慧天地最近,Goodwin调查发现,在城市地区,接近30%的交通拥堵源自于司机寻找停车位。据称,到2020年,将会有20亿的汽车在公路上跑着,这就意味着,届时汽车的数量将比目前多了7.7亿辆…