正文
错误处理
package chapter3
import (
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
)
type appHandler func(writer http.ResponseWriter,
request *http.Request)error
func errWrapper(
handler appHandler)func( writer http.ResponseWriter,
request *http.Request){
return func(writer http.ResponseWriter,
request *http.Request){
err:=handler(writer,request)
if err!=nil{
code:=http.StatusOK
switch {
case os.IsNotExist(err):
code=http.StatusNotFound
default:
code=http.StatusInternalServerError
}
http.Error(writer,
http.StatusText(code),
code)
}
}
}
func main(){
http.HandleFunc("/list/",errWrapper(filehandle))
http.ListenAndServe(":8888",nil)
}
const prefix="/list/"
type userError string
func(e userError)Error()string{
return e.Message()
}
func (e userError)Message()string{
return string(e)
}
func filehandle(writer http.ResponseWriter,
request *http.Request)error {
if strings.Index(request.URL.Path,prefix)!=0{
return errors.New("path must start"+
"with"+prefix)
}
path:=request.URL.Path[len("/list/"):]
//统一错误处理
file,err:=os.Open(path)
if err!=nil{
http.Error(writer,
err.Error(),
http.StatusInternalServerError)
return
}
defer file.Close()
all,err:=ioutil.ReadAll(file)
if err!=nil{
log.Printf("Error occurred"+
"handling request:%s" ,
err.Error())
}
if err!=nil{
return err
}
writer.Write(all)
return nil
}
//服务器统一错误处理
func tryRecover(){
defer func(){
//错误处理的核心,在于recover函数,
如果是已知的错误,可以把它recover
如果是未知的错误,则要提示维护者。
r:=recover()
if err,ok:=r.(error);ok{
fmt.Println("Error occurred:",err)
}else{
panic(fmt.Sprintf(" i dont know"))
}
}()
}
// error vs panic
//defer panic recover