在 REST API 上进行错误处理

我很陌生,已经部署了一个带有 API 端点的小型服务。


我听说/读到 go 不使用,try/catch所以我想弄清楚如何从我的 API 的服务调用中“捕获”发生的任何问题,并确保资源服务器不会停机。


我的 API 代码如下所示..


我有一个routes.go包含以下内容的文件


package main


import (

    "net/http"


    "github.com/gorilla/mux"

)


type Route struct {

    Name        string

    Method      string

    Pattern     string

    HandlerFunc http.HandlerFunc

}


type Routes []Route


func NewRouter() *mux.Router {

    router := mux.NewRouter().StrictSlash(true)

    for _, route := range routes {

        router.

            Methods(route.Method).

            Path(route.Pattern).

            Name(route.Name).

            Handler(route.HandlerFunc)

    }


    return router

}


var routes = Routes{

    Route{

        "CustomerLocationCreate",

        "POST",

        "/tracking/customer",

        CustomerLocationCreate,

    },

}

我有一个 handlers.go


package main


import (

    "encoding/json"

    "net/http"

    "io"

    "io/ioutil"

)


//curl -H "Content-Type: application/json" -d '{"userId":"1234"}' http://localhost:8181/tracking/customer

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

    var location CustomerLocation

    body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))

    if err != nil {

        panic(err)

    }

    if err := r.Body.Close(); err != nil {

        panic(err)

    }

    if err := json.Unmarshal(body, &location); err != nil {

        w.Header().Set("Content-Type", "application/json; charset=UTF-8")

        w.WriteHeader(422) // unprocessable entity

        if err := json.NewEncoder(w).Encode(err); err != nil {

            panic(err)

        }

    }


    c := RepoCreateCustomerLocation(location)

    w.Header().Set("Content-Type", "application/json; charset=UTF-8")

    w.WriteHeader(http.StatusCreated)

    if err := json.NewEncoder(w).Encode(c); err != nil {

        panic(err)

    }


    HandleCustomerLocationChange(c);

}

我的问题是我应该如何修改HandleCustomerLocationChange(...) function and if necessaryCustomerLocationChange(..)` 处理程序以正确处理错误,以便在发生错误时,我的整个 API 不会出现故障?


蝴蝶不菲
浏览 165回答 1
1回答

饮歌长啸

Go 提出了一种不同的方法,错误不是例外,它们是正常事件,只是不太常见。以上面的代码为例:body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))if err != nil {    panic(err)}在这里,恐慌(没有恢复)终止了进程,关闭了 Web 服务器。似乎对没有完全阅读请求的反应过于严厉。你想让我做什么?告诉提出请求的客户可能是合适的:body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))if err != nil {    http.Error(w, err.Error(), http.StatusBadRequest)    return}您可能希望返回一个 json 编码的响应,或者向客户端提供通用消息以避免暴露太多,并记录特定的错误详细信息。对于一般函数,将错误作为最后一个返回参数返回是惯用的。在你提到的具体例子中:func HandleCustomerLocationChange(custLoc CustomerLocation) ...    conn, err := amqp.Dial(...)    failOnError(err, "Failed to connect to RabbitMQ")相反,检查连接是否失败,并将错误返回给调用者。在调用函数中处理它,或添加信息并将其向上传播到调用堆栈。func HandleCustomerLocationChange(custLoc CustomerLocation) error...    conn, err := amqp.Dial(...)    if err != nil {        return fmt.Errorf("failed to connect to RabbitMQ: %s", err)    }以这种方式传播错误给出了根本原因的简明解释,例如5 个为什么技术,例如:“没有更新客户端位置:没有连接到rabbitmq:网络地址1.2.3无法访问”另一个约定是先处理错误并尽早返回。这有助于减少嵌套。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go