go语言学习-使用函数式编程封装错误

下面这段代码的主要功能就是建立一个http服务端,通过这个http服务端我们可以在web端查看本地的文件内容。
但是在我们访问的时候如果url输入不正确,就会出现异常,我们通过函数式编程的方式,对http.handleFunc的第二个入参做了封装,让他从一个没有错误返回的函数,变成了一个有错误返回的函数,我们在外面统一进行了错误处理。
下面就是代码以及说明:

package main

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

const prefix="/list/"

type uesrError string //用来在web端显示错误

func (e uesrError)Error() string{
	return e.Message()
}

func (e uesrError)Message() string{
	return string(e)
}

func playFileListHandle(w http.ResponseWriter,r *http.Request) error{

	if strings.Index(r.URL.Path,prefix)!=0{
		return uesrError("path must start"+prefix)
	}

	path := r.URL.Path[len(prefix):]
	file ,err := os.Open(path)
	if err !=nil{
		return err
	}
	defer file.Close()

	all,err := ioutil.ReadAll(file)
	if err != nil{
		return err
	}

	w.Write(all)
	 return nil
}

//定义一个函数类型 appHandler 这样就可以将错误返回
type appHandler func(w http.ResponseWriter,r *http.Request) error


//这个函数的入参是一个返回值是error的函数类型,返回值是一个和入参函数有着相同的入参的函数,
// 但是不带返回值,这样做的目的是为了匹配http.HandleFunc,因为http.HandleFunc的第二
// 个参数没有返回值,这样就可以把一个原本没有返回值的函数变成一个有错误返回的函数,这样我们就可以
//在外面对错误进行统一的处理
func errWrapper(handler appHandler) func(w http.ResponseWriter,r *http.Request) {

	return func(w http.ResponseWriter,r* http.Request){

		defer func(){
				r := recover()
				log.Printf("panic is %v",r)
				http.Error(w,http.StatusText(http.StatusInternalServerError),
					http.DefaultMaxHeaderBytes)
				return
		}()
		err := handler(w,r)
		if err != nil {
			code := http.StatusOK
			if userErr,ok := err.(uesrError);ok{
				http.Error(w,userErr.Message(),http.StatusBadRequest)
			}
			switch {
				case os.IsNotExist(err):
					code = http.StatusNotFound
			default:
					code = http.StatusInternalServerError
			}
			http.Error(w,http.StatusText(code),code)
		}
	}
}

func main() {

	http.HandleFunc("/",errWrapper(playFileListHandle))
	err :=http.ListenAndServe(":8080",nil)

	if err !=nil{
		log.Fatal(err.Error())
	}
}

看完之后,小伙伴们如果有不懂的地方欢迎提问。

欢迎关注问我团队公众号:

在这里插入图片描述

参考内容:慕课网 ccmouse

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值