feat(be/settings): add api for reporting client error

This commit is contained in:
hexxa 2021-12-27 16:52:30 +08:00 committed by Hexxa
parent 4fd9bd9c33
commit 7577fb0ace
5 changed files with 67 additions and 2 deletions

View file

@ -54,3 +54,10 @@ func (cl *SettingsClient) SetClientCfg(cfg *sitestore.ClientConfig, token *http.
}). }).
End() End()
} }
func (cl *SettingsClient) ReportError(report *settings.ClientErrorReport, token *http.Cookie) (*http.Response, string, []error) {
return cl.r.Post(cl.url("/v1/settings/errors")).
AddCookie(token).
Send(report).
End()
}

View file

@ -66,6 +66,7 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
apiRuleCname(userstore.AdminRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(userstore.AdminRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/settings/client"): true, apiRuleCname(userstore.AdminRole, "GET", "/v1/settings/client"): true,
apiRuleCname(userstore.AdminRole, "PATCH", "/v1/settings/client"): true, apiRuleCname(userstore.AdminRole, "PATCH", "/v1/settings/client"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/settings/errors"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/captchas/"): true, apiRuleCname(userstore.AdminRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.AdminRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(userstore.AdminRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.AdminRole, "POST", "/v1/fs/sharings"): true, apiRuleCname(userstore.AdminRole, "POST", "/v1/fs/sharings"): true,
@ -97,6 +98,7 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
apiRuleCname(userstore.UserRole, "GET", "/v1/fs/metadata"): true, apiRuleCname(userstore.UserRole, "GET", "/v1/fs/metadata"): true,
apiRuleCname(userstore.UserRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(userstore.UserRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/settings/client"): true, apiRuleCname(userstore.UserRole, "GET", "/v1/settings/client"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/settings/errors"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/captchas/"): true, apiRuleCname(userstore.UserRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.UserRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(userstore.UserRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.UserRole, "POST", "/v1/fs/sharings"): true, apiRuleCname(userstore.UserRole, "POST", "/v1/fs/sharings"): true,
@ -114,6 +116,7 @@ func NewMultiUsersSvc(cfg gocfg.ICfg, deps *depidx.Deps) (*MultiUsersSvc, error)
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/dirs"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/dirs"): true,
apiRuleCname(userstore.VisitorRole, "OPTIONS", "/v1/settings/health"): true, apiRuleCname(userstore.VisitorRole, "OPTIONS", "/v1/settings/health"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/settings/client"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/settings/client"): true,
apiRuleCname(userstore.VisitorRole, "POST", "/v1/settings/errors"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/imgs"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/captchas/imgs"): true,
apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/exist"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/exist"): true,

View file

@ -77,3 +77,20 @@ func validateClientCfg(cfg *sitestore.ClientConfig) error {
} }
return nil return nil
} }
type ClientErrorReport struct {
Report string `json:"report"`
Version string `json:"version"`
}
func (h *SettingsSvc) ReportError(c *gin.Context) {
var err error
req := &ClientErrorReport{}
if err = c.ShouldBindJSON(&req); err != nil {
c.JSON(q.ErrResp(c, 400, err))
return
}
h.deps.Log().Errorf("version:%s,error:%s", req.Version, req.Report)
c.JSON(q.Resp(200))
}

View file

@ -304,6 +304,7 @@ func initHandlers(router *gin.Engine, cfg gocfg.ICfg, deps *depidx.Deps) (*gin.E
settingsAPI.OPTIONS("/health", settingsSvc.Health) settingsAPI.OPTIONS("/health", settingsSvc.Health)
settingsAPI.GET("/client", settingsSvc.GetClientCfg) settingsAPI.GET("/client", settingsSvc.GetClientCfg)
settingsAPI.PATCH("/client", settingsSvc.SetClientCfg) settingsAPI.PATCH("/client", settingsSvc.SetClientCfg)
settingsAPI.POST("/errors", settingsSvc.ReportError)
return router, nil return router, nil
} }

View file

@ -1,9 +1,14 @@
package server package server
import ( import (
"fmt"
"github.com/ihexxa/quickshare/src/handlers/settings"
"io/ioutil"
"os" "os"
"reflect" "reflect"
"strings"
"testing" "testing"
"time"
"github.com/ihexxa/quickshare/src/client" "github.com/ihexxa/quickshare/src/client"
"github.com/ihexxa/quickshare/src/db/sitestore" "github.com/ihexxa/quickshare/src/db/sitestore"
@ -43,13 +48,12 @@ func TestSettingsHandlers(t *testing.T) {
adminName := "qs" adminName := "qs"
adminPwd := "quicksh@re" adminPwd := "quicksh@re"
userPwd := "1234" userPwd := "1234"
// adminNewPwd := "quicksh@re2"
setUpEnv(t, rootPath, adminName, adminPwd) setUpEnv(t, rootPath, adminName, adminPwd)
defer os.RemoveAll(rootPath) defer os.RemoveAll(rootPath)
srv := startTestServer(config) srv := startTestServer(config)
defer srv.Shutdown() defer srv.Shutdown()
// fs := srv.depsFS() fs := srv.depsFS()
if !isServerReady(addr) { if !isServerReady(addr) {
t.Fatal("fail to start server") t.Fatal("fail to start server")
@ -121,4 +125,37 @@ func TestSettingsHandlers(t *testing.T) {
} }
} }
}) })
t.Run("ReportError", func(t *testing.T) {
settingsCl := client.NewSettingsClient(addr)
reportContent := `{state: "{}", error: "empty state"}`
report := &settings.ClientErrorReport{
Report: reportContent,
Version: "0.0.1",
}
reportResp, _, errs := settingsCl.ReportError(report, adminToken)
if len(errs) > 0 {
t.Fatal(errs)
} else if reportResp.StatusCode != 200 {
t.Fatal(reportResp.StatusCode)
}
file, id, err := fs.GetFileReader("quickshare.log")
if err != nil {
t.Fatal(err)
}
defer fs.CloseReader(fmt.Sprint(id))
// TODO: it is flaky
time.Sleep(time.Duration(1) * time.Second)
content, err := ioutil.ReadAll(file)
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(content), `"msg":"version:0.0.1,error:{state: \"{}\", error: \"empty state\"}"`) {
t.Fatalf("log does not contain error: %s", content)
}
})
} }