forked from Gitlink/gitlink-cli
fix(client): support gateway error format and wiki/open paths
Cherry-picked from co63oc's PR #193: - Handle gateway {"code":N, "msg":"..."} error format - Extend success status codes (201, 204) - Exclude wiki/open paths from .json suffix auto-append Co-Authored-By: co63oc <4617245+co63oc@users.noreply.github.com>
This commit is contained in:
parent
f9f96cfedc
commit
339900785f
|
|
@ -115,22 +115,35 @@ func (c *Client) Do(method, path string, body interface{}, query url.Values) (*o
|
|||
}
|
||||
|
||||
// Check GitLink error-in-body pattern
|
||||
// Support both {"status":N, "message":"..."} and gateway {"code":N, "msg":"..."}
|
||||
var bodyCode float64
|
||||
var bodyMsg string
|
||||
if status, ok := raw["status"]; ok {
|
||||
var statusCode float64
|
||||
switch v := status.(type) {
|
||||
case float64:
|
||||
statusCode = v
|
||||
bodyCode = v
|
||||
case int:
|
||||
statusCode = float64(v)
|
||||
bodyCode = float64(v)
|
||||
}
|
||||
if statusCode != 0 && statusCode != 200 && statusCode != 1 {
|
||||
msg, _ := raw["message"].(string)
|
||||
suggestion := suggestFix(int(statusCode))
|
||||
return output.ErrorEnvelope(int(statusCode), msg, suggestion), &APIError{
|
||||
StatusCode: int(statusCode),
|
||||
Code: int(statusCode),
|
||||
Message: msg,
|
||||
}
|
||||
bodyMsg, _ = raw["message"].(string)
|
||||
} else if code, ok := raw["code"]; ok {
|
||||
switch v := code.(type) {
|
||||
case float64:
|
||||
bodyCode = v
|
||||
case int:
|
||||
bodyCode = float64(v)
|
||||
}
|
||||
bodyMsg, _ = raw["msg"].(string)
|
||||
if bodyMsg == "" {
|
||||
bodyMsg, _ = raw["message"].(string)
|
||||
}
|
||||
}
|
||||
if bodyCode != 0 && bodyCode != 200 && bodyCode != 201 && bodyCode != 204 && bodyCode != 1 {
|
||||
suggestion := suggestFix(int(bodyCode))
|
||||
return output.ErrorEnvelope(int(bodyCode), bodyMsg, suggestion), &APIError{
|
||||
StatusCode: int(bodyCode),
|
||||
Code: int(bodyCode),
|
||||
Message: bodyMsg,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -175,6 +188,10 @@ func shouldAppendJSONSuffix(path string) bool {
|
|||
return false
|
||||
}
|
||||
}
|
||||
// Wiki open API endpoints do not use .json suffix
|
||||
if len(parts) >= 3 && parts[0] == "wiki" && parts[1] == "open" {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -169,6 +169,45 @@ func TestClientDoStatusError(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestClientDoGatewayCodeError(t *testing.T) {
|
||||
// Gateway returns {"code":N, "msg":"..."} instead of {"status":N, "message":"..."}
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"code":400,"msg":"Bad Request"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
|
||||
env, err := c.Do("GET", "/api/test", nil, nil)
|
||||
if err == nil {
|
||||
t.Fatal("expected error for code=400")
|
||||
}
|
||||
if env == nil {
|
||||
t.Fatal("expected envelope for code error")
|
||||
}
|
||||
if env.OK {
|
||||
t.Fatal("expected OK=false for code=400")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientDoGatewayCode201Success(t *testing.T) {
|
||||
// Gateway returns code=201 with JSON string data — should be treated as success
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write([]byte(`{"code":201,"msg":"","data":"{\"title\":\"test\"}"}`))
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
c := &Client{HTTP: server.Client(), BaseURL: server.URL}
|
||||
env, err := c.Do("POST", "/api/test", map[string]string{"title": "test"}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error for code=201: %v", err)
|
||||
}
|
||||
if !env.OK {
|
||||
t.Fatal("expected OK=true for code=201")
|
||||
}
|
||||
}
|
||||
|
||||
func TestClientDoStatusZero(t *testing.T) {
|
||||
// status=0, 200, 1 are treated as success
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
@ -525,3 +564,18 @@ func TestShouldAppendJSONSuffixSkipsExistingJSONPath(t *testing.T) {
|
|||
t.Fatal("existing .json path should not get another suffix")
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldAppendJSONSuffixSkipsWikiOpenPaths(t *testing.T) {
|
||||
paths := []string{
|
||||
"/wiki/open/createWiki",
|
||||
"/wiki/open/getWiki",
|
||||
"/wiki/open/updateWiki",
|
||||
"/wiki/open/deleteWiki",
|
||||
"/wiki/open/wikiPages",
|
||||
}
|
||||
for _, p := range paths {
|
||||
if shouldAppendJSONSuffix(p) {
|
||||
t.Errorf("wiki/open path %q should not get .json suffix", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue