diff --git a/api/error.go b/api/error.go index eaf32b7..dcc6ecb 100644 --- a/api/error.go +++ b/api/error.go @@ -13,26 +13,21 @@ type Error struct { Arguments []interface{} `json:"arguments"` } -// WrapError returns a new error from a base error with errorarguments. -func WrapError(baseError Error, arguments ...interface{}) Error { - for _, arg := range arguments { - baseError.Put(arg) - } - return baseError -} - -// Put adds an argument to the error +// SetArguments set one or multiple arguments to the error // to be displayed back to API caller -func (e *Error) Put(arg interface{}) { +func (e *Error) SetArguments(arg0 interface{}, args ...interface{}) { - /* (1) Make slice if not */ - if e.Arguments == nil { - e.Arguments = make([]interface{}, 0) + // 1. clear arguments */ + e.Arguments = make([]interface{}, 0) + + // 2. add arg[0] + e.Arguments = append(e.Arguments, arg0) + + // 3. add optional other arguments + for _, arg := range args { + e.Arguments = append(e.Arguments, arg) } - /* (2) Append argument */ - e.Arguments = append(e.Arguments, arg) - } // Implements 'error' diff --git a/api/response.go b/api/response.go index 2ea4e6f..d8bd700 100644 --- a/api/response.go +++ b/api/response.go @@ -33,38 +33,46 @@ func NewResponse(errors ...Error) *Response { return res } +// WrapError sets the error from a base error with error arguments. +func (res *Response) WrapError(baseError Error, arguments ...interface{}) { + if len(arguments) > 0 { + baseError.SetArguments(arguments[0], arguments[1:]) + } + res.Err = baseError +} + // SetData adds/overrides a new response field -func (i *Response) SetData(name string, value interface{}) { - i.Data[name] = value +func (res *Response) SetData(name string, value interface{}) { + res.Data[name] = value } // GetData gets a response field -func (i *Response) GetData(name string) interface{} { - value, _ := i.Data[name] +func (res *Response) GetData(name string) interface{} { + value, _ := res.Data[name] return value } // MarshalJSON implements the 'json.Marshaler' interface and is used // to generate the JSON representation of the response -func (i *Response) MarshalJSON() ([]byte, error) { +func (res *Response) MarshalJSON() ([]byte, error) { fmt := make(map[string]interface{}) - for k, v := range i.Data { + for k, v := range res.Data { fmt[k] = v } - fmt["error"] = i.Err + fmt["error"] = res.Err return json.Marshal(fmt) } // Write writes to an HTTP response. -func (i *Response) Write(w http.ResponseWriter) error { - w.WriteHeader(i.Status) +func (res *Response) Write(w http.ResponseWriter) error { + w.WriteHeader(res.Status) w.Header().Add("Content-Type", "application/json") - fmt, err := json.Marshal(i) + fmt, err := json.Marshal(res) if err != nil { return err } diff --git a/server.go b/server.go index b3d4d42..6964f60 100644 --- a/server.go +++ b/server.go @@ -112,13 +112,15 @@ func (s *Server) ServeHTTP(res http.ResponseWriter, req *http.Request) { // fail if found no handler if serviceHandler == nil { if serviceFound { - apiResponse := api.NewResponse(api.WrapError(api.ErrorUncallableMethod(), servicePath, req.Method)) + apiResponse := api.NewResponse() + apiResponse.WrapError(api.ErrorUncallableMethod(), servicePath, req.Method) apiResponse.Write(res) logError(apiResponse) return } - apiResponse := api.NewResponse(api.WrapError(api.ErrorUncallableService(), servicePath)) + apiResponse := api.NewResponse() + apiResponse.WrapError(api.ErrorUncallableService(), servicePath) apiResponse.Write(res) logError(apiResponse) return diff --git a/util.go b/util.go index b027634..2550d1b 100644 --- a/util.go +++ b/util.go @@ -23,7 +23,9 @@ func (s *Server) extractParameters(store *reqdata.Store, methodParam map[string] // 2. fail if required & missing if !isset && !param.Optional { - return nil, api.WrapError(api.ErrorMissingParam(), name) + apiErr := api.ErrorMissingParam() + apiErr.SetArguments(name) + return nil, apiErr } // 3. optional & missing: set default value @@ -50,7 +52,9 @@ func (s *Server) extractParameters(store *reqdata.Store, methodParam map[string] // 5. fail on unexpected multipart file waitFile, gotFile := param.Type == "FILE", p.File if gotFile && !waitFile || !gotFile && waitFile { - return nil, api.WrapError(api.ErrorInvalidParam(), param.Rename, "FILE") + apiErr := api.ErrorInvalidParam() + apiErr.SetArguments(param.Rename, "FILE") + return nil, apiErr } // 6. do not check if file @@ -61,7 +65,9 @@ func (s *Server) extractParameters(store *reqdata.Store, methodParam map[string] // 7. check type if s.Checkers.Run(param.Type, p.Value) != nil { - return nil, api.WrapError(api.ErrorInvalidParam(), param.Rename, param.Type, p.Value) + apiErr := api.ErrorInvalidParam() + apiErr.SetArguments(param.Rename, param.Type, p.Value) + return nil, apiErr } parameters[param.Rename] = p.Value