Golang:程序的错误处理方式

/ Golang / 没有评论 / 1904浏览

golang的错误处理方式

利用函数编程,将错误分为用户可见和系统信息。这里利用打开文件列表的服务测试的,强调的是程序中尽量少出现panic,因为这个会终止掉程序,server程序不会被终止是因为有recover保护。

web.go 这个文件功能主要是处理各种错误

  package main

import (
	"./filelist"
	"fmt"
	"net/http"
	"os"
)

type appHandler func(writer http.ResponseWriter, request *http.Request) error

func errWrapper(handler appHandler) func(http.ResponseWriter,*http.Request){
	return func(writer http.ResponseWriter, request *http.Request) {
		defer func() {
			r := recover() //自己recover掉
			if r != nil{
				fmt.Println("panic:",r)
				http.Error(writer,http.StatusText(http.StatusInternalServerError),http.StatusInternalServerError)
			}
		}()
		err := handler(writer,request)
		if err != nil{

			if userErr, ok := err.(userError); ok{
				http.Error(writer,
					userErr.Message(),
					http.StatusBadRequest)
				return
			}

			code := http.StatusOK
			switch {
			case os.IsNotExist(err):
				//http.Error(writer,http.StatusText(http.StatusNotFound),http.StatusNotFound)
				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(filelist.HandleFileList))

	err := http.ListenAndServe(":8888",nil)
	if err != nil{
		panic(err)
	}

}

handler.go 这个文件主要是在网页中访问服务器,显示服务器上的内容的。主要是打开文件,读取所有内容打印出来

package filelist

import (
	"io/ioutil"
	"net/http"
	"os"
	"strings"
)

const filePath = "/awesomeProject/"

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{

	if (strings.Index(request.URL.Path,filePath)) != 0{
		return userError("path is error")
	}
	path := request.URL.Path[len("/Users/ryan/Documents/go_code/awesomeProject/"):]
	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
}