如何正确地重构go语言中的错误处理?

3

我刚开始学习Go语言,还不太熟悉它的编程模式。

我有一个Web服务器,用作代理其他远程服务的中转。我使用来映射路由到处理程序,代码使用了App Engine。

// imports ommited.

func init() {
  m = mux.NewRouter()
  m.HandleFunc("/ponies", listPonies)
  m.HandleFunc("/rainbows", listRainbows)
  http.Handle("/", m)
}

func listPonies(w http.ResponseWriter, r *http.Request) {
  ponies, err := ponyService.getAll()

  if err != nil {
      w.write(err.Error())
      return;
  }

  w.write(string(ponies))
}

func listRainbows(w http.ResponseWriter, r *http.Request) {
  rainbows, err := rainbowService.getAll()

  if err != nil {
      w.write(err.Error())
      return;
  }

  w.write(string(rainbows))
}

我希望将常见代码(错误处理、转换为字符串和编写响应)重构为一个单一的函数。我的第一次尝试仅仅是定义一个通用函数进行调用:
func handleErrorAndWriteResponse(w http.ResponseWriter, obj Stringer, err error) {
  if err != nil {
      w.write(err.Error())
      return;
  }

  w.write(string(obj))
}

并像这样调用它

func listPonies(w http.ResponseWriter, r *http.Request) {
  handleErrorAndWriteResponse(w, ponyService.getAll())       
}

func listRainbows(w http.ResponseWriter, r *http.Request) {
  handleErrorAndWriteResponse(w, rainbowService.getAll())
}

但是

  1. 它不起作用。我收到了一个“参数不足”的错误。这可能与将多个响应值混合使用有关,因为这些值不能直接转换为调用函数的参数。
  2. 我不喜欢传递错误参数的想法。也许这没问题,只是看起来很不干净。但我还不太了解Go。

那么,什么是“正确的方法”(或Go的方法)?

1个回答

4

有一篇golang.org关于错误处理的博客文章,专门讨论了AppEngine应用程序中的错误处理。特别是,请查看“简化重复错误处理”部分。

处理错误的方法基本上是让您的处理函数在失败的情况下返回一个error,然后使用常见的错误处理程序包装对它们的调用:

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

func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if err := fn(w, r); err != nil {
        http.Error(w, err.Error(), 500)
    }
}

func listPonies(w http.ResponseWriter, r *http.Request) error {
    ponies, err := ponyService.getAll()

    if err != nil {
        return err;
    }

    w.write(string(ponies))
}

你还需要以不同的方式注册处理程序:
func init() {
    http.Handle("/view", appHandler(listPonies))
}

1
我在这里也问了一个类似的问题(附带更多的实现细节),展示了另一种解决方法:https://dev59.com/AHzaa4cB1Zd3GeqPKQAs#21511199 - elithrar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接