error.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package httputils
  15. import (
  16. "bytes"
  17. "fmt"
  18. )
  19. // New a http Json client error
  20. // code: http error code, >=400
  21. // class: error class
  22. // msg: message
  23. // params: message format parameters
  24. func NewJsonClientError(code int, class string, msgFmt string, params ...interface{}) *JSONClientError {
  25. details := msgFmt
  26. if len(params) > 0 {
  27. details = fmt.Sprintf(msgFmt, params...)
  28. }
  29. theErr := Error{
  30. Id: msgFmt,
  31. Fields: params,
  32. }
  33. return &JSONClientError{Code: code, Class: class, Details: details, Data: theErr}
  34. }
  35. func msgFmtToTmpl(msgFmt string) string {
  36. // 将%s %d之类格式化字符串转换成{0}、{1}格式
  37. // 注意: 1.不支持复杂类型的转换例如%.2f , %[1]d, % x
  38. // 2.原始msgFmt中如果包含{0},{1}形式的字符串同样会引发错误。
  39. // 在抛出error msgFmt时应注意避免
  40. fmtstr := false
  41. lst := []rune(msgFmt)
  42. lastIndex := len(lst) - 1
  43. temp := bytes.Buffer{}
  44. index := 0
  45. for i, c := range lst {
  46. switch c {
  47. case '%':
  48. if fmtstr || i == lastIndex {
  49. temp.WriteRune(c)
  50. fmtstr = false
  51. } else {
  52. fmtstr = true
  53. }
  54. case 'v', 'T', 't', 'b', 'c', 'd', 'o', 'q', 'x', 'X', 'U', 'e', 'E', 'f', 'F', 'g', 'G', 's', 'p':
  55. if fmtstr {
  56. temp.WriteRune('{')
  57. temp.WriteString(fmt.Sprintf("%d", index))
  58. temp.WriteRune('}')
  59. index++
  60. fmtstr = false
  61. } else {
  62. temp.WriteRune(c)
  63. }
  64. default:
  65. if fmtstr {
  66. temp.WriteRune('%')
  67. }
  68. temp.WriteRune(c)
  69. fmtstr = false
  70. }
  71. }
  72. return temp.String()
  73. }
  74. func MsgTmplToFmt(tmpl string) string {
  75. return msgTmplToFmt(tmpl)
  76. }
  77. func msgTmplToFmt(tmpl string) string {
  78. b := &bytes.Buffer{}
  79. for i := 0; i < len(tmpl); {
  80. r := tmpl[i]
  81. if r != '{' {
  82. b.WriteByte(r)
  83. i++
  84. continue
  85. }
  86. j := i + 1
  87. for ; j < len(tmpl); j++ {
  88. r := tmpl[j]
  89. if r < '0' || r > '9' {
  90. break
  91. }
  92. }
  93. if j == len(tmpl) {
  94. b.WriteString(tmpl[i:])
  95. return b.String()
  96. }
  97. if j > i+1 && tmpl[j] == '}' {
  98. b.WriteString("%s")
  99. i = j + 1
  100. } else {
  101. b.WriteString(tmpl[i:j])
  102. i = j
  103. }
  104. }
  105. return b.String()
  106. }