httperrors: 支持从msgTmpl转换为带%s的msgFmt

This commit is contained in:
Yousong Zhou
2019-06-28 15:06:32 +00:00
parent d5f4e5eecf
commit 1416a1fe98
2 changed files with 74 additions and 25 deletions
+48 -8
View File
@@ -26,13 +26,13 @@ func NewJsonClientError(code int, title string, msg string, error httputils.Erro
return &err
}
func msgToTemplate(msg string) string {
func msgFmtToTmpl(msgFmt string) string {
// 将%s %d之类格式化字符串转换成{0}、{1}格式
// 注意: 1.不支持复杂类型的转换例如%.2f , %[1]d, % x
// 2.原始msg中如果包含{0},{1}形式的字符串同样会引发错误。
// 在抛出error msg时应注意避免
// 2.原始msgFmt中如果包含{0},{1}形式的字符串同样会引发错误。
// 在抛出error msgFmt时应注意避免
fmtstr := false
lst := []rune(msg)
lst := []rune(msgFmt)
lastIndex := len(lst) - 1
temp := bytes.Buffer{}
index := 0
@@ -68,18 +68,58 @@ func msgToTemplate(msg string) string {
return temp.String()
}
func errorMessage(msg string, params ...interface{}) (string, httputils.Error) {
func MsgTmplToFmt(tmpl string) string {
return msgTmplToFmt(tmpl)
}
func msgTmplToFmt(tmpl string) string {
b := &bytes.Buffer{}
for i := 0; i < len(tmpl); {
r := tmpl[i]
if r != '{' {
b.WriteByte(r)
i++
continue
}
j := i + 1
for ; j < len(tmpl); j++ {
r := tmpl[j]
if r < '0' || r > '9' {
break
}
}
if j == len(tmpl) {
b.WriteString(tmpl[i:])
return b.String()
}
if j > i+1 && tmpl[j] == '}' {
b.WriteString("%s")
i = j + 1
} else {
b.WriteString(tmpl[i:j])
i = j
}
}
return b.String()
}
func errorMessage(msgFmt string, params ...interface{}) (string, httputils.Error) {
fields := make([]string, len(params))
for i, v := range params {
fields[i] = fmt.Sprint(v)
}
error := httputils.Error{Id: msgToTemplate(msg), Fields: fields}
err := httputils.Error{
Id: msgFmtToTmpl(msgFmt),
Fields: fields,
}
msg := msgFmt
if len(params) > 0 {
msg = fmt.Sprintf(msg, params...)
}
return msg, error
return msg, err
}
func NewBadGatewayError(msg string, params ...interface{}) *httputils.JSONClientError {
+26 -17
View File
@@ -65,35 +65,44 @@ func TestVariadic(t *testing.T) {
}
}
func TestMsgToTemplate(t *testing.T) {
func TestMsgFmtTmplConversion(t *testing.T) {
cases := []struct {
name string
msg string
params []interface{}
out string
name string
msgFmt string
msgTmpl string
msgFmt2 string
params []interface{}
out string
}{
{
name: "non-empty msg to template",
msg: "%% baremetals %s delete.time %d%",
out: "% baremetals {0} delete.time {1}%",
name: "empty",
msgFmt: "",
msgTmpl: "",
msgFmt2: "",
},
{
name: "empty msg to template",
msg: "",
out: "",
name: "non-empty",
msgFmt: "%% baremetals %s delete.time %d%",
msgTmpl: "% baremetals {0} delete.time {1}%",
msgFmt2: "% baremetals %s delete.time %s%",
},
{
name: "non-empty with zh-utf8 characters msg to template",
msg: "%% baremetals %s 中文%d ¥%%",
out: "% baremetals {0} 中文{1} ¥%",
name: "non-empty with zh-utf8",
msgFmt: "%% baremetals %s 中文%d ¥%%",
msgTmpl: "% baremetals {0} 中文{1} ¥%",
msgFmt2: "% baremetals %s 中文%s ¥%",
},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
resp := msgToTemplate(c.msg)
if resp != c.out {
t.Errorf("want %s, got %s", c.out, resp)
msgTmpl := msgFmtToTmpl(c.msgFmt)
if msgTmpl != c.msgTmpl {
t.Errorf("msgFmtToTmpl: want %s, got %s", c.msgTmpl, msgTmpl)
}
msgFmt2 := msgTmplToFmt(msgTmpl)
if msgFmt2 != c.msgFmt2 {
t.Errorf("msgTmplToFmt: want %s, got %s", c.msgFmt2, msgFmt2)
}
})
}