From f4740e77e86dcb345a38bd1de32262506fc72590 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 29 Aug 2014 16:03:44 -0700 Subject: [PATCH] Aggregate all errors with their URLS in status.json in one place. Change-Id: If7a540fc3d1a6caa94b5f04d44de3207f15ac4cf --- pkg/importer/importer.go | 13 ++++++++----- pkg/server/status.go | 22 ++++++++++++++++++---- pkg/types/camtypes/statustype.go | 22 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 pkg/types/camtypes/statustype.go diff --git a/pkg/importer/importer.go b/pkg/importer/importer.go index e90cc9eb0..f96e62ed9 100644 --- a/pkg/importer/importer.go +++ b/pkg/importer/importer.go @@ -39,6 +39,7 @@ import ( "camlistore.org/pkg/search" "camlistore.org/pkg/server" "camlistore.org/pkg/syncutil" + "camlistore.org/pkg/types/camtypes" ) const ( @@ -351,8 +352,9 @@ type accountStatus struct { // AccountsStatus returns the currently configured accounts and their status for // inclusion in the status.json document, as rendered by the web UI. -func (h *Host) AccountsStatus() interface{} { +func (h *Host) AccountsStatus() (interface{}, []camtypes.StatusError) { var s []accountStatus + var errs []camtypes.StatusError for _, impName := range h.importers { imp := h.imp[impName] accts, _ := imp.Accounts() @@ -371,15 +373,16 @@ func (h *Host) AccountsStatus() interface{} { } if ia.lastRunErr != nil { as.LastError = ia.lastRunErr.Error() + errs = append(errs, camtypes.StatusError{ + Error: ia.lastRunErr.Error(), + URL: ia.AccountURL(), + }) } ia.mu.Unlock() s = append(s, as) } } - s = append(s, accountStatus{ - Name: "hi", - }) - return s + return s, errs } func (h *Host) InitHandler(hl blobserver.FindHandlerByTyper) error { diff --git a/pkg/server/status.go b/pkg/server/status.go index d40af3c08..ef85061aa 100644 --- a/pkg/server/status.go +++ b/pkg/server/status.go @@ -22,6 +22,7 @@ import ( "html" "log" "net/http" + "os" "reflect" "regexp" "strings" @@ -33,6 +34,7 @@ import ( "camlistore.org/pkg/index" "camlistore.org/pkg/jsonconfig" "camlistore.org/pkg/search" + "camlistore.org/pkg/types/camtypes" ) // StatusHandler publishes server status information. @@ -100,7 +102,7 @@ func (sh *StatusHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) { type status struct { Version string `json:"version"` - Error string `json:"error,omitempty"` + Errors []camtypes.StatusError `json:"errors,omitempty"` Sync map[string]syncStatus `json:"sync"` Storage map[string]storageStatus `json:"storage"` rootPrefix string @@ -109,6 +111,13 @@ type status struct { ImporterAccounts interface{} `json:"importerAccounts"` } +func (st *status) addError(msg, url string) { + st.Errors = append(st.Errors, camtypes.StatusError{ + Error: msg, + URL: url, + }) +} + func (st *status) isHandler(pfx string) bool { if pfx == st.ImporterRoot { return true @@ -137,9 +146,12 @@ func (sh *StatusHandler) currentStatus() *status { Storage: make(map[string]storageStatus), Sync: make(map[string]syncStatus), } + if v := os.Getenv("CAMLI_FAKE_STATUS_ERROR"); v != "" { + res.addError(v, "/status/#fakeerror") + } _, hi, err := sh.handlerFinder.FindHandlerByType("root") if err != nil { - res.Error = fmt.Sprintf("Error finding root handler: %v", err) + res.addError(fmt.Sprintf("Error finding root handler: %v", err), "") return res } rh := hi.(*RootHandler) @@ -148,9 +160,11 @@ func (sh *StatusHandler) currentStatus() *status { if pfx, h, err := sh.handlerFinder.FindHandlerByType("importer"); err == nil { res.ImporterRoot = pfx as := h.(interface { - AccountsStatus() interface{} + AccountsStatus() (interface{}, []camtypes.StatusError) }) - res.ImporterAccounts = as.AccountsStatus() + var errs []camtypes.StatusError + res.ImporterAccounts, errs = as.AccountsStatus() + res.Errors = append(res.Errors, errs...) } types, handlers := sh.handlerFinder.AllHandlers() diff --git a/pkg/types/camtypes/statustype.go b/pkg/types/camtypes/statustype.go new file mode 100644 index 000000000..74705ab5d --- /dev/null +++ b/pkg/types/camtypes/statustype.go @@ -0,0 +1,22 @@ +/* +Copyright 2014 The Camlistore Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package camtypes + +type StatusError struct { + Error string `json:"error"` + URL string `json:"url,omitempty"` // optional +}