Go学习:错误的处理

编程入门 行业动态 更新时间:2024-10-12 10:23:59

Go学习:<a href=https://www.elefans.com/category/jswz/34/1771449.html style=错误的处理"/>

Go学习:错误的处理

不对错误进行处理

package mainimport ("bufio""fmt""learngo/errhandling/fib""os"
)func writeFlie(fileName string) {file, err := os.OpenFile(fileName, os.O_EXCL|os.O_CREATE, 0666)if err != nil {panic(err)}defer file.Close()writer := bufio.NewWriter(file)defer writer.Flush()f := fib.Fib()for i := 0; i < 20; i++ {fmt.Fprintln(writer, f())}
}func main() {/**panic: open fib.txt: The file exists.goroutine 1 [running]:main.writeFlie({0x250faa, 0x7})D:/gospace/learngo/errhandling/defer/defer.go:14 +0x367main.main()D:/gospace/learngo/errhandling/defer/defer.go:28 +0x25*/writeFlie("fib.txt")
}

不对错误进行处理时,程序会直接挂掉并且会打印一些报错信息

错误处理一

package mainimport ("bufio""fmt""learngo/errhandling/fib""os"
)func writeFlie(fileName string) {file, err := os.OpenFile(fileName, os.O_EXCL|os.O_CREATE, 0666)if err != nil {if pathError, ok := err.(*os.PathError); !ok {panic(err)}else {fmt.Printf("%s, %s, %s\n",pathError.Op,pathError.Path,pathError.Err)}}defer file.Close()writer := bufio.NewWriter(file)defer writer.Flush()f := fib.Fib()for i := 0; i < 20; i++ {fmt.Fprintln(writer, f())}
}func main() {// open, fib.txt, The file exists.writeFlie("fib.txt")
}

错误处理二

package filelistingimport ("io/ioutil""net/http""os"
)func HandleFileList(writer http.ResponseWriter, request *http.Request) error {path := request.URL.Path[len("/list/"):]file, err := os.Open(path)if err != nil {return err}defer file.Close()all, err := ioutil.ReadAll(file)if err != nil {return err}writer.Write(all)return nil
}
package mainimport ("learngo/errhandling/filelistingserver/filelisting""log""net/http""os"
)type appHandler func(writer http.ResponseWriter, request *http.Request) errorfunc errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) {return func(writer http.ResponseWriter, request *http.Request) {err := handler(writer, request)if err != nil {log.Printf("Error occurred "+"handling request: %s",err.Error())code := http.StatusOKswitch {case os.IsNotExist(err):code = http.StatusNotFoundcase os.IsPermission(err):code = http.StatusForbiddendefault:code = http.StatusInternalServerError}http.Error(writer,http.StatusText(code),code)}}
}func main() {http.HandleFunc("/list/",errWrapper(filelisting.HandleFileList))err := http.ListenAndServe(":8888", nil)if err != nil {panic(err)}
}
  • 正常访问

  • 文件不存在

  • 日志

最终版

package mainimport ("learngo/errhandling/filelistingserver/filelisting""log""net/http""os"
)type appHandler func(writer http.ResponseWriter, request *http.Request) errortype userError interface {errorMessage() string
}func errWrapper(handler appHandler) func(http.ResponseWriter, *http.Request) {return func(writer http.ResponseWriter, request *http.Request) {defer func() {if r := recover(); r != nil {log.Printf("Panic: %v", r)http.Error(writer,http.StatusText(http.StatusInternalServerError),http.StatusInternalServerError)}}()err := handler(writer, request)if err != nil {log.Printf("Error occurred "+"handling request: %s", err.Error())// userErrorif userErr, ok := err.(userError); ok {http.Error(writer,userErr.Message(),http.StatusBadRequest)return}// systemErrorcode := http.StatusOKswitch {case os.IsNotExist(err):code = http.StatusNotFoundcase os.IsPermission(err):code = http.StatusForbiddendefault:code = http.StatusInternalServerError}http.Error(writer,http.StatusText(code),code)}}
}func main() {http.HandleFunc("/",errWrapper(filelisting.HandleFileList))err := http.ListenAndServe(":8888", nil)if err != nil {panic(err)}
}
package filelistingimport ("fmt""io/ioutil""net/http""os""strings"
)const prefix = "/list/"type userError stringfunc (e userError) Error() string {return e.Message()
}
func (e userError) Message() string {return string(e)
}func HandleFileList(writer http.ResponseWriter, request *http.Request) error {if strings.Index(request.URL.Path, prefix) != 0 {return userError(fmt.Sprintf("path %s must start with %s",request.URL.Path,prefix))}path := request.URL.Path[len("/list/"):]file, err := os.Open(path)if err != nil {return err}defer file.Close()all, err := ioutil.ReadAll(file)if err != nil {return err}writer.Write(all)return nil
}
  • 路由错误

  • 文件不存在

  • 正常访问

  • 日志

总结

recover

  • 仅再defer调用中调用
  • 获取panic的值
  • 如果无法处理,可重新panic

error VS panic

  • panic尽量不要用,尽量使用error
  • 意料之中的:使用error.如:文件打不开
  • 意料之外的:使用panic.如:数组越界

错误处理综合示例

  • defer + panic + recpver
  • Type Assertion处理error
  • 函数式编程调用

更多推荐

Go学习:错误的处理

本文发布于:2023-07-28 19:27:20,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1287141.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:错误

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!