error.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // Copyright 2021 Tencent Inc. All rights reserved.
  2. package core
  3. import (
  4. "bytes"
  5. "encoding/json"
  6. "fmt"
  7. "net/http"
  8. "strings"
  9. )
  10. // APIError 微信支付 API v3 标准错误结构
  11. type APIError struct {
  12. StatusCode int // 应答报文的 HTTP 状态码
  13. Header http.Header // 应答报文的 Header 信息
  14. Body string // 应答报文的 Body 原文
  15. Code string `json:"code"` // 应答报文的 Body 解析后的错误码信息,仅不符合预期/发生系统错误时存在
  16. Message string `json:"message"` // 应答报文的 Body 解析后的文字说明信息,仅不符合预期/发生系统错误时存在
  17. Detail interface{} `json:"detail,omitempty"` // 应答报文的 Body 解析后的详细信息,仅不符合预期/发生系统错误时存在
  18. }
  19. // Error 输出 APIError
  20. func (e *APIError) Error() string {
  21. var buf bytes.Buffer
  22. _, _ = fmt.Fprintf(&buf, "error http response:[StatusCode: %d Code: \"%s\"", e.StatusCode, e.Code)
  23. if e.Message != "" {
  24. _, _ = fmt.Fprintf(&buf, "\nMessage: %s", e.Message)
  25. }
  26. if e.Detail != nil {
  27. var detailBuf bytes.Buffer
  28. enc := json.NewEncoder(&detailBuf)
  29. enc.SetIndent("", " ")
  30. if err := enc.Encode(e.Detail); err == nil {
  31. _, _ = fmt.Fprint(&buf, "\nDetail:")
  32. _, _ = fmt.Fprintf(&buf, "\n%s", strings.TrimSpace(detailBuf.String()))
  33. }
  34. }
  35. if len(e.Header) > 0 {
  36. _, _ = fmt.Fprint(&buf, "\nHeader:")
  37. for key, value := range e.Header {
  38. _, _ = fmt.Fprintf(&buf, "\n - %v=%v", key, value)
  39. }
  40. }
  41. _, _ = fmt.Fprintf(&buf, "]")
  42. return buf.String()
  43. }
  44. // IsAPIError 判断当前 error 是否为特定 Code 的 *APIError
  45. //
  46. // 类型为其他 error 或 Code 不匹配时均返回 false
  47. func IsAPIError(err error, code string) bool {
  48. if ne, ok := err.(*APIError); ok {
  49. return ne.Code == code
  50. }
  51. return false
  52. }