1
0
mirror of https://github.com/raseels-repos/golang-saas-starter-kit.git synced 2025-06-06 23:46:29 +02:00
Lee Brown 227af02f31 issue#16 web-app account signup
Account signup works with validation and translations.
2019-07-31 13:47:30 -08:00

122 lines
2.9 KiB
Go

package weberror
import (
"context"
"geeks-accelerator/oss/saas-starter-kit/internal/platform/web/webcontext"
"net/http"
"github.com/pkg/errors"
)
// Error is used to pass an error during the request through the
// application with web specific context.
type Error struct {
Err error
Status int
Fields []FieldError
Cause error
Message string
}
// FieldError is used to indicate an error with a specific request field.
type FieldError struct {
Field string `json:"field"`
FormField string `json:"-"`
Value interface{} `json:"value"`
Tag string `json:"tag"`
Error string `json:"error"`
Display string `json:"display"`
}
// NewError wraps a provided error with an HTTP status code. This
// function should be used when handlers encounter expected errors.
func NewError(ctx context.Context, er error, status int) error {
webErr, ok := er.(*Error)
if ok {
return webErr
}
// If the error was of the type *Error, the handler has
// a specific status code and error to return.
webErr, ok = errors.Cause(er).(*Error)
if ok {
return webErr
}
// Ensure the error is not a validation error.
if ne, ok := NewValidationError(ctx, er); ok {
return ne
}
if er == webcontext.ErrContextRequired {
return NewShutdownError(er.Error())
}
// If not, the handler sent any arbitrary error value so use 500.
if status == 0 {
status = http.StatusInternalServerError
}
cause := errors.Cause(er)
if cause == nil {
cause = er
}
return &Error{er, status, nil, cause, ""}
}
// Error implements the error interface. It uses the default message of the
// wrapped error. This is what will be shown in the services' logs.
func (err *Error) Error() string {
return err.Err.Error()
}
// Display renders an error that can be returned as ErrorResponse to the user via the API.
func (er *Error) Display(ctx context.Context) ErrorResponse {
var r ErrorResponse
if er.Message != "" {
r.Error = er.Message
} else {
r.Error = er.Error()
}
if len(er.Fields) > 0 {
r.Fields = er.Fields
}
return r
}
// ErrorResponse is the form used for API responses from failures in the API.
type ErrorResponse struct {
Error string `json:"error"`
Fields []FieldError `json:"fields,omitempty"`
}
// String returns the ErrorResponse formatted as a string.
func (er ErrorResponse) String() string {
str := er.Error
if len(er.Fields) > 0 {
for _, f := range er.Fields {
str = str + "\t" + f.Error + "\n"
}
}
return str
}
// NewErrorMessage wraps a provided error with an HTTP status code and message. The
// message value is given priority and returned as the error message.
func NewErrorMessage(ctx context.Context, er error, status int, msg string) error {
return WithMessage(ctx, NewError(ctx, er, status), msg)
}
// WithMessage appends the error with a message.
func WithMessage(ctx context.Context, er error, msg string) error {
weberr := NewError(ctx, er, 0).(*Error)
weberr.Message = msg
return weberr
}