zoukankan      html  css  js  c++  java
  • 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) } }
  • 相关阅读:
    聊聊高并发系统之限流特技
    Java动态代理机制详解(JDK 和CGLIB,Javassist,ASM)
    密码技术(图解密码技术的学习总结)
    Nginx配置
    Nginx与浏览器缓存
    JAVA类加载和初始化
    [TimLinux] JavaScript 模态框可拖动功能实现——节流版
    [TimLinux] JavaScript 模态框可拖动功能实现——原始版
    [TimLinux] Python3 Coverity zeep/SOAP 库使用示例
    [TimLinux] Vue.js -- Day02 -- 第一个示例
  • 原文地址:https://www.cnblogs.com/vincenshen/p/9318015.html
Copyright © 2011-2022 走看看