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的更多相关文章

  1. Go语言异常处理defer\panic\recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  2. go语言defer panic recover用法总结

    defer defer是go提供的一种资源处理的方式.defer的用法遵循3个原则 在defer表达式被运算的同时,defer函数的参数也会被运算.如下defer的表达式println运算的同时,其入 ...

  3. [Go] 如何正确地 抛出 错误 和 异常(error/panic/recover)?

    序言 错误 和 异常 是两个不同的概念,非常容易混淆.很多程序员习惯将一切非正常情况都看做错误,而不区分错误和异常,即使程序中可能有异常抛出,也将异常及时捕获并转换成错误.从表面上看,一切皆错误的思路 ...

  4. go panic recover 异常处理

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  5. defer,panic,recover

    Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常,甚至一个小小的错误都抛出一个 ...

  6. defer, panic, recover使用总结

    1. defer : 延迟调用.多个defer,依次入栈,在函数即将退出时,依次出栈调用 package main import "fmt" func main() { defer ...

  7. Go的异常处理 defer, panic, recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  8. 探究 Go 源码中 panic & recover 有哪些坑?

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客: https://www.luozhiyun.com/archives/627 本文使用的go的源码1.17.3 前言 写这一篇文章的原因是 ...

  9. 闭包 panic recover

    闭包=函数+外层变量的引用 recover必须搭配defer使用 defer一定要在可能引发panic的语句之前定义

随机推荐

  1. phpcms v9 配置sphinx全文索引教程

    英文介绍:http://www.sphinxsearch.com/docs/manual-0.9.9.html 一.首先需要在服务器上安装sphinx 在Windows上安装sphinx     1. ...

  2. APP全局异常捕获,并保存本地文件

    public class CrashHandler implements Thread.UncaughtExceptionHandler { public static final String TA ...

  3. TP分页

    ①在Home下设置Publics文件夹或在thinkPHP下library的vender 把page.class.php 考贝进入 ②通过new 实例化方式调用 $page=new \Home\Pub ...

  4. docker-compose安装confluence

    1.首先安装docker-compose   pip install docker-compose       安装完成提示:         2.编写mysql-confluence-compose ...

  5. POJ 1039 Pipe【经典线段与直线相交】

    链接: http://poj.org/problem?id=1039 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ...

  6. ASP-DateAdd时间增加

    ASP内置函数DateAdd(interval, number, date) 1.interval标识你要加的日期部分,具体参数如下:yyyy → 年m → 月d → 日h → 小时n → 分钟s → ...

  7. MySQL中阻塞

    因为不同锁之间的兼容性关系,在有些时刻一个事务中的锁需要等待另一个事务中的锁释放它占有的资源,这就是阻塞.阻塞不是一件坏事,是为了保证事务可以并发并且正常的运行 在InnoDB存储引擎中,参数inno ...

  8. python爬虫--爬取cctv连续剧

    #encoding=utf-8 import requests from bs4 import BeautifulSoup import re import os from aria2rpc impo ...

  9. mysql大致学习路径

  10. OpenCV3计算机视觉+Python(五)

    人脸检测和识别 本章将介绍Haar级联分类器,通过对比分析相邻图像区域来判断给定图像或子图像与已知对象是否匹配.本章将考虑如何将多个Haar级联分类器构成一个层次结构,即一个分类器能识别整体区域(如人 ...