Go panic recover
panic
1. 停止当前函数执行
2. 一直向上返回,执行每一层的defer
3. 如果没有遇到recover, 程序退出
recover
1. 仅在defer调用中使用
2. 获取panic的值
3. 如果无法处理,可重新panic
示例1
package main import (
"errors"
"fmt"
) func tryRecover() {
defer func() {
r := recover()
// r.(type) 判断对象的类型
if err, ok := r.(error); ok {
fmt.Println("Error occurred:", err)
} else {
panic(r)
}
}()
panic(errors.New("this is an error"))
} func main() {
tryRecover()
}
示例2: 处理Web Error
errorHandler.go
package filelisting import (
"net/http"
"os"
"io/ioutil"
"strings"
) const prefix = "/list/" type userError string func (e userError) Error() string {
return e.Message()
} func (e userError) Message() string {
return string(e)
} func HandleFileList(writer http.ResponseWriter, request *http.Request) error {
index := strings.Index(request.URL.Path, prefix)
if index != 0 {
return userError("path must start with " + prefix)
}
path := request.URL.Path[len(prefix):]
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()
bytes, err := ioutil.ReadAll(file)
if err != nil {
return err
}
writer.Write(bytes)
return nil
}
web.go
package main import (
"net/http"
"imooc/errhanding/filelistingserver/filelisting"
"os"
"log"
) type appHandler func(writer http.ResponseWriter, request *http.Request) error
// error装饰器
func errWrapper(handler appHandler) func(writer http.ResponseWriter, request *http.Request) {
return func(writer http.ResponseWriter, request *http.Request) {
defer func() {
if r := recover(); r != nil {
log.Println("Panic: ", r)
http.Error(writer, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
}
}()
err := handler(writer, request)
if err != nil {
logger := log.New(os.Stdout, "[Warn]", log.Lshortfile)
logger.Printf("Error handling request: %s", err.Error()) // 自定义user error...
if userErr, ok := err.(userError); ok {
http.Error(writer, userErr.Message(), http.StatusBadRequest)
return
} code := http.StatusOK
switch {
case os.IsNotExist(err):
code = http.StatusNotFound
case os.IsPermission(err):
code = http.StatusForbidden
default:
code = http.StatusInternalServerError
}
http.Error(writer, http.StatusText(code), code)
}
}
} type userError interface {
error
Message() string
} func main() {
http.HandleFunc("/", errWrapper(filelisting.HandleFileList)) err := http.ListenAndServe(":8888", nil)
if err != nil {
panic(err)
}
}
Go panic recover的更多相关文章
- Go语言异常处理defer\panic\recover
Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...
- go语言defer panic recover用法总结
defer defer是go提供的一种资源处理的方式.defer的用法遵循3个原则 在defer表达式被运算的同时,defer函数的参数也会被运算.如下defer的表达式println运算的同时,其入 ...
- [Go] 如何正确地 抛出 错误 和 异常(error/panic/recover)?
序言 错误 和 异常 是两个不同的概念,非常容易混淆.很多程序员习惯将一切非正常情况都看做错误,而不区分错误和异常,即使程序中可能有异常抛出,也将异常及时捕获并转换成错误.从表面上看,一切皆错误的思路 ...
- go panic recover 异常处理
Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...
- defer,panic,recover
Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个 ...
- defer, panic, recover使用总结
1. defer : 延迟调用.多个defer,依次入栈,在函数即将退出时,依次出栈调用 package main import "fmt" func main() { defer ...
- Go的异常处理 defer, panic, recover
Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...
- 探究 Go 源码中 panic & recover 有哪些坑?
转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/627 本文使用的go的源码1.17.3 前言 写这一篇文章的原因是 ...
- 闭包 panic recover
闭包=函数+外层变量的引用 recover必须搭配defer使用 defer一定要在可能引发panic的语句之前定义
随机推荐
- Zookeeper权限管理与Quota管理
Zookeeper的ACL机制和Quota机制网上资料较少,这里做一个总结,以供大家参考. 1 Zookeeper ACL ZooKeeper的权限管理亦即ACL控制功能通过Server.Client ...
- 用js判断页面是否加载完成
这可以通过用document.onreadystatechange的方法来监听状态改变, 然后用document.readyState == “complete”判断是否加载完成. 可以采用2个div ...
- Instapaper 使用经验和技巧
Instapaper 分类本质是文件夹整理,没有标签. 文件夹意味着一篇文章只能放在一个文件夹里,不像标签可以实现一篇文章多个标签的功能. 一.文件夹和Like功能 1.已有文件夹: Home:存放所 ...
- Sping Cloud 微服务框架学习
Spring Cloud官方中文站 https://springcloud.cc
- jquery lazyload延迟加载技术的实现原理分析_jquery
前言 懒加载技术(简称lazyload)并不是新技术,它是js程序员对网页性能优化的一种方案.lazyload的核心是按需加载.在大型网站中都有lazyload的身影,例如谷歌的图片搜索页,迅雷首页, ...
- DBProxy 入门到精通系列(一):DBProxy概述
DBProxy概述 DBProxy是支持分库分表,读写分离的中间件,博客内容除了阅读github官方文档外,还会附加上本人个人测试的结果,但了解一个中间件,需要对这个中间件有一个基本的认识,方便控制. ...
- (2.3)学习笔记之mysql基础操作(表/库操作)
本系列学习笔记主要讲如下几个方面: 本文笔记[六:表操作--线上可以直接删除表吗?] 附加:库操作 [1]创建制定字符集的数据库 需求描述: 在创建DB的时候指定字符集. 操作过程: 1.使用crea ...
- spring 编译时抱错纪录class path resource [spring/] cannot be resolved to URL because it does not exist
class path resource [spring/] cannot be resolved to URL because it does not exist; 在 pom.xml 里添加如下代码 ...
- numpy利用数组进行数据处理
将条件逻辑表述为数组运算 numpy.where()是一个三目运算的表达式 In [34]: xarr = np.array([1.1,1.2,1.3,1.4,1.5]) In [35]: yarr ...
- JavaScript:学习笔记(2)——基本概念与数据类型
JavaScript:学习笔记(2)——基本概念与数据类型 语法 1.区分大小写.Test 和 test 是完全不同的两个变量. 2.语句最好以分号结束,也就是说不以分号结束也可以. 变量 1.JS的 ...