diff --git a/src/client/settings.go b/src/client/settings.go index 4983e19..be22442 100644 --- a/src/client/settings.go +++ b/src/client/settings.go @@ -54,3 +54,10 @@ func (cl *SettingsClient) SetClientCfg(cfg *sitestore.ClientConfig, token *http. }). 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() +} diff --git a/src/handlers/multiusers/handlers.go b/src/handlers/multiusers/handlers.go index eded733..7722851 100644 --- a/src/handlers/multiusers/handlers.go +++ b/src/handlers/multiusers/handlers.go @@ -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, "GET", "/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/imgs"): 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, "OPTIONS", "/v1/settings/health"): 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/imgs"): 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, "OPTIONS", "/v1/settings/health"): 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/imgs"): true, apiRuleCname(userstore.VisitorRole, "GET", "/v1/fs/sharings/exist"): true, diff --git a/src/handlers/settings/handlers.go b/src/handlers/settings/handlers.go index 607f98a..c7bb434 100644 --- a/src/handlers/settings/handlers.go +++ b/src/handlers/settings/handlers.go @@ -77,3 +77,20 @@ func validateClientCfg(cfg *sitestore.ClientConfig) error { } 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)) +} diff --git a/src/server/server.go b/src/server/server.go index 59ec8ac..bbd7841 100644 --- a/src/server/server.go +++ b/src/server/server.go @@ -304,6 +304,7 @@ func initHandlers(router *gin.Engine, cfg gocfg.ICfg, deps *depidx.Deps) (*gin.E settingsAPI.OPTIONS("/health", settingsSvc.Health) settingsAPI.GET("/client", settingsSvc.GetClientCfg) settingsAPI.PATCH("/client", settingsSvc.SetClientCfg) + settingsAPI.POST("/errors", settingsSvc.ReportError) return router, nil } diff --git a/src/server/server_settings_test.go b/src/server/server_settings_test.go index c3267f9..b758053 100644 --- a/src/server/server_settings_test.go +++ b/src/server/server_settings_test.go @@ -1,9 +1,14 @@ package server import ( + "fmt" + "github.com/ihexxa/quickshare/src/handlers/settings" + "io/ioutil" "os" "reflect" + "strings" "testing" + "time" "github.com/ihexxa/quickshare/src/client" "github.com/ihexxa/quickshare/src/db/sitestore" @@ -43,13 +48,12 @@ func TestSettingsHandlers(t *testing.T) { adminName := "qs" adminPwd := "quicksh@re" userPwd := "1234" - // adminNewPwd := "quicksh@re2" setUpEnv(t, rootPath, adminName, adminPwd) defer os.RemoveAll(rootPath) srv := startTestServer(config) defer srv.Shutdown() - // fs := srv.depsFS() + fs := srv.depsFS() if !isServerReady(addr) { 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) + } + }) }