Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Go 停止HTTP调用并使用处理程序链返回错误;可能吗?_Go_Handler_Middleware - Fatal编程技术网

Go 停止HTTP调用并使用处理程序链返回错误;可能吗?

Go 停止HTTP调用并使用处理程序链返回错误;可能吗?,go,handler,middleware,Go,Handler,Middleware,使用以下代码(取自): 主程序包 进口( “字节” “编码/json” “io” “io/ioutil” “日志” “net/http” ) 类型有效负载结构{ 名称字符串 位置字符串 } func readSecond(w http.ResponseWriter,r*http.Request){ log.Println(“输入readSecond”) //r.Body是io.ReadCloser,这就是我们所知道的 b、 err:=ioutil.ReadAll(r.Body) 如果错误!=零{

使用以下代码(取自):

主程序包
进口(
“字节”
“编码/json”
“io”
“io/ioutil”
“日志”
“net/http”
)
类型有效负载结构{
名称字符串
位置字符串
}
func readSecond(w http.ResponseWriter,r*http.Request){
log.Println(“输入readSecond”)
//r.Body是io.ReadCloser,这就是我们所知道的
b、 err:=ioutil.ReadAll(r.Body)
如果错误!=零{
log.Fatal(错误)
}
//关闭一个关闭器不会伤害任何人
延迟r.Body.Close()
Printf(“请求正文:%s”,字符串(b))
}
func readFirst(w http.ResponseWriter,r*http.Request){
log.Println(“输入readFirst”)
//临时缓冲区
b:=bytes.NewBuffer(make([]字节,0))
//TeeReader返回一个读卡器,该读卡器将从r.Body读取的内容写入b。
读卡器:=io.TEERADER(右主体,b)
//一些商业逻辑
var有效载荷
如果err:=json.NewDecoder(reader).Decode(&payload);err!=nil{
log.Fatal(错误)
}
//我们的身体完了
延迟r.Body.Close()
Printf(“来自正文的反序列化负载:%v”,负载)
//nocloser返回一个ReadCloser,其中包含一个no-op-Close方法,该方法包装提供的读取器r。
r、 Body=ioutil.nocloser(b)
}
func处理程序(w http.ResponseWriter,r*http.Request){
readFirst(w,r)
读秒(w,r)
}
func main(){
http.HandleFunc(“/”,handler)
log.Fatal(http.ListenAndServe(“:8080”,nil))
}
是否有方法阻止运行
readSecond()
(第二个处理程序)

例如:

如果
payload==”
我想退出HTTP调用并返回一个错误

有没有办法使用此代码执行此操作?


我知道我可以用嵌套中间件来实现。但是像这样的处理程序会怎么样呢?

使用方法和接收器有助于更好地控制错误。 您不能在http的处理程序中定期返回错误

package main

import (
    "bytes"
    "encoding/json"
    "io"
    "io/ioutil"
    "log"
    "net/http"
)

type Payload struct {
    Name     string
    Location string
}

type Handle struct {
    err error
}

func (h *Handle) readSecond(w http.ResponseWriter, r *http.Request) {
    log.Println("entering readSecond")

    // r.Body is a io.ReadCloser, that's all we know
    b, err := ioutil.ReadAll(r.Body)
    if err != nil {
        log.Fatal(err)
    }

    // closing a NopCloser won't hurt anybody
    defer r.Body.Close()

    log.Printf("request body: %s", string(b))
}

func (h *Handle) readFirst(w http.ResponseWriter, r *http.Request) {
    log.Println("entering readFirst")
    h.err = nil

    // temporary buffer
    b := bytes.NewBuffer(make([]byte, 0))

    // TeeReader returns a Reader that writes to b what it reads from r.Body.
    reader := io.TeeReader(r.Body, b)

    // some business logic
    var payload Payload
    if err := json.NewDecoder(reader).Decode(&payload); err != nil {
        // log.Fatal("read first", err)
        h.err = err
        w.Write([]byte(err.Error()))
    }

    // we are done with body
    defer r.Body.Close()

    log.Printf("deserialized payload from body: %v", payload)

    // NopCloser returns a ReadCloser with a no-op Close method wrapping the provided Reader r.
    r.Body = ioutil.NopCloser(b)
}

func handler(w http.ResponseWriter, r *http.Request) {
    var handle Handle
    handle.readFirst(w, r)
    if handle.err == nil {
        handle.readSecond(w, r)
    }
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

为了改变行为,必须进行一些更改,所以当你说“使用此代码”时,你试图避免什么样的更改?@Adrian尽可能少?有没有具体的原因说明你不能从
readFirst
返回错误?您的
readX
函数都不需要满足
HandlerFunc
类型。@kingkupps,您的意思是错误,这样我就可以在
readFirst()
之后检查它了?是的!我在问为什么不先将签名
func readFirst(w http.ResponseWriter,r*http.Request)设置为错误
,然后检查返回的错误或缺少错误。