• 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) } }
  • 相关阅读:
    vs2013配置opencv2.4.13(txt中复制粘贴即可,一次配置永久使用)
    描述性统计量
    Ubuntu创建、删除文件与目录
    Linux下服务器端开发流程及相关工具介绍(C++)
    TCP 协议如何保证可靠传输
    真实记录疑似Linux病毒导致服务器 带宽跑满的解决过程
    Windbg程序调试--转载
    原来问题在这里-我的memory leak诊断历程
    用WinDbg分析Debug Diagnostic Tool生成的Userdump文件
    一个内存增长问题的分析和处理(三)
  • 原文地址:https://www.cnblogs.com/vincenshen/p/9318015.html
Copyright © 2020-2023  润新知