Handling errors for debugging in Go

huangapple go评论123阅读模式
英文:

Handling errors for debugging in Go

问题

我想知道在调试应用程序时,是否有更好的处理错误的方法。我想设置一个名为'debug'的标志,它将显示从函数返回的真实错误(例如来自SQL)。如果未设置该标志,我希望返回一个通用的消息。

我在这里创建了一个按照这种方式工作的示例:
http://play.golang.org/p/YDeqVvRSMd

总体思路是我将真实错误和我的默认错误传递给一个函数,并检查是否设置了debug标志:

  1. func ErrorMsg(debug, error_type error) map[string]interface{} {
  2. var msg error
  3. if Debug {
  4. msg = debug
  5. } else {
  6. msg = error_type
  7. }
  8. err := map[string]interface{}{"error_message": msg}
  9. return err
  10. }

然而,这种方法似乎有些丑陋。有没有更好的方法来实现这个目标?

另外,我想返回一个JSON响应,这就是为什么使用了一个map的原因。

英文:

I'm wondering if there are any better methods for handling errors in an application for debugging. I want to have a flag like 'debug' set, and it will display the real errors returned (like for example from sql) from the functions. If it isn't set I want it to return a generic message.

I made something that works this way here:
http://play.golang.org/p/YDeqVvRSMd

The general idea is I pass the real error and my stock error into a function and it checks to see if debug is set:

  1. func ErrorMsg(debug, error_type error) map[string]interface{} {
  2. var msg error
  3. if Debug {
  4. msg = debug
  5. } else {
  6. msg = error_type
  7. }
  8. err := map[string]interface{}{"error_message": msg}
  9. return err
  10. }

However this kinda seems like an ugly solution. Is there a better way to accomplish this?

Also I want to return a JSON response, which is why it's a map.

答案1

得分: 2

Go是一种非常冗长的语言,你无法做太多来简化代码,这是一个稍微缩短一点的版本:

  1. func ErrorMsg(debug, error_type error) map[string]interface{} {
  2. msg := error_type
  3. if Debug {
  4. msg = debug
  5. }
  6. return map[string]interface{}{"error_message": msg}
  7. }

或者你可以完全去掉map,直接返回错误并在错误结构体上设置json标签:

  1. type RequestError struct {
  2. ErrorString string `json:"error_message"`
  3. }
  4. func ErrorMsg(debug, error_type error) (err error) {
  5. err = error_type
  6. if Debug {
  7. err = debug
  8. }
  9. return
  10. }

playground

英文:

Go is a very verbose language, there isn't much you can do to clean that code up, here's a tiny bit shorter version:

  1. func ErrorMsg(debug, error_type error) map[string]interface{} {
  2. msg := error_type
  3. if Debug {
  4. msg = debug
  5. }
  6. return map[string]interface{}{"error_message": msg}
  7. }

Or you can drop the map all together and return the error directly and set json tags on the error struct:

  1. type RequestError struct {
  2. ErrorString string `json:"error_message"`
  3. }
  4. func ErrorMsg(debug, error_type error) (err error) {
  5. err = error_type
  6. if Debug {
  7. err = debug
  8. }
  9. return
  10. }

<kbd>playground</kbd>

答案2

得分: 2

你可以创建一个名为DebugError的类型,其中包含显示错误和调试错误,该类型还应实现Error接口。然后,你可以使用一个辅助函数来打印错误。

  1. package main
  2. import (
  3. "errors"
  4. "fmt"
  5. )
  6. var ErrInternal = errors.New("Internal Server Error")
  7. type DebugError struct {
  8. Display error
  9. Debug error
  10. }
  11. // Error实现了error接口
  12. // 使用Display错误
  13. func (err DebugError) Error() string {
  14. return err.Display.Error()
  15. }
  16. func main() {
  17. err := someSqlCall()
  18. if err != nil {
  19. // 调试错误
  20. fmt.Println(getError(err, true))
  21. // 显示错误
  22. fmt.Println(getError(err, false))
  23. }
  24. }
  25. // 模拟SQL函数
  26. func someSqlCall() error {
  27. return DebugError{
  28. Display: ErrInternal,
  29. Debug: errors.New("Real sql error goes here"),
  30. }
  31. }
  32. // getError是一个辅助函数,返回调试或显示错误
  33. func getError(err error, debug bool) error {
  34. debugErr, ok := err.(DebugError)
  35. if !ok {
  36. // 不是调试错误
  37. return err
  38. }
  39. if debug {
  40. return debugErr.Debug
  41. }
  42. return debugErr.Display
  43. }

Go Playground

附注:个人而言,我会保持简单,并记录所有的错误。

英文:

You could create a DebugError type that contains both your display and debug error, this type would also implement the Error interface. Then you could use a helper function to print the error.

  1. package main
  2. import (
  3. &quot;errors&quot;
  4. &quot;fmt&quot;
  5. )
  6. var ErrInternal = errors.New(&quot;Internal Server Error&quot;)
  7. type DebugError struct {
  8. Display error
  9. Debug error
  10. }
  11. // Error implements the error interface
  12. // Uses the Display error
  13. func (err DebugError) Error() string {
  14. return err.Display.Error()
  15. }
  16. func main() {
  17. err := someSqlCall()
  18. if err != nil {
  19. // debug error
  20. fmt.Println(getError(err, true))
  21. // display error
  22. fmt.Println(getError(err, false))
  23. }
  24. }
  25. // mock sql function
  26. func someSqlCall() error {
  27. return DebugError{
  28. Display: ErrInternal,
  29. Debug: errors.New(&quot;Real sql error goes here&quot;),
  30. }
  31. }
  32. // getError is a helper function that returns a debug or display error
  33. func getError(err error, debug bool) error {
  34. debugErr, ok := err.(DebugError)
  35. if !ok {
  36. // not a debug error
  37. return err
  38. }
  39. if debug {
  40. return debugErr.Debug
  41. }
  42. return debugErr.Display
  43. }

Go play.

P.S. Personally I keep it simple and log all of my errors.

huangapple
  • 本文由 发表于 2014年10月3日 03:20:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/26168036.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定