mirror of
				https://github.com/labstack/echo.git
				synced 2025-10-30 23:57:38 +02:00 
			
		
		
		
	HTTPError#Message is now interface
Signed-off-by: Vishal Rana <vr@labstack.com>
This commit is contained in:
		
							
								
								
									
										83
									
								
								echo.go
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								echo.go
									
									
									
									
									
								
							| @@ -42,7 +42,7 @@ import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"log" | ||||
| 	slog "log" | ||||
| 	"net/http" | ||||
| 	"path" | ||||
| 	"reflect" | ||||
| @@ -51,7 +51,7 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/labstack/gommon/color" | ||||
| 	glog "github.com/labstack/gommon/log" | ||||
| 	"github.com/labstack/gommon/log" | ||||
| 	"github.com/tylerb/graceful" | ||||
| 	"golang.org/x/crypto/acme/autocert" | ||||
| ) | ||||
| @@ -59,23 +59,23 @@ import ( | ||||
| type ( | ||||
| 	// Echo is the top-level framework instance. | ||||
| 	Echo struct { | ||||
| 		DisableHTTP2 bool | ||||
| 		Debug        bool | ||||
| 		HTTPErrorHandler | ||||
| 		Binder          Binder | ||||
| 		Renderer        Renderer | ||||
| 		AutoTLSManager  autocert.Manager | ||||
| 		ShutdownTimeout time.Duration | ||||
| 		Color           *color.Color | ||||
| 		Logger          Logger | ||||
| 		server          *graceful.Server | ||||
| 		tlsServer       *graceful.Server | ||||
| 		premiddleware   []MiddlewareFunc | ||||
| 		middleware      []MiddlewareFunc | ||||
| 		maxParam        *int | ||||
| 		router          *Router | ||||
| 		notFoundHandler HandlerFunc | ||||
| 		pool            sync.Pool | ||||
| 		DisableHTTP2     bool | ||||
| 		Debug            bool | ||||
| 		HTTPErrorHandler HTTPErrorHandler | ||||
| 		Binder           Binder | ||||
| 		Renderer         Renderer | ||||
| 		AutoTLSManager   autocert.Manager | ||||
| 		ShutdownTimeout  time.Duration | ||||
| 		Color            *color.Color | ||||
| 		Logger           Logger | ||||
| 		server           *graceful.Server | ||||
| 		tlsServer        *graceful.Server | ||||
| 		premiddleware    []MiddlewareFunc | ||||
| 		middleware       []MiddlewareFunc | ||||
| 		maxParam         *int | ||||
| 		router           *Router | ||||
| 		notFoundHandler  HandlerFunc | ||||
| 		pool             sync.Pool | ||||
| 	} | ||||
|  | ||||
| 	// Route contains a handler and information for matching against requests. | ||||
| @@ -88,7 +88,7 @@ type ( | ||||
| 	// HTTPError represents an error that occurred while handling a request. | ||||
| 	HTTPError struct { | ||||
| 		Code    int | ||||
| 		Message string | ||||
| 		Message interface{} | ||||
| 	} | ||||
|  | ||||
| 	// MiddlewareFunc defines a function to process middleware. | ||||
| @@ -240,13 +240,13 @@ func New() (e *Echo) { | ||||
| 			Prompt: autocert.AcceptTOS, | ||||
| 		}, | ||||
| 		ShutdownTimeout: 15 * time.Second, | ||||
| 		Logger:          glog.New("echo"), | ||||
| 		Logger:          log.New("echo"), | ||||
| 		maxParam:        new(int), | ||||
| 		Color:           color.New(), | ||||
| 	} | ||||
| 	e.HTTPErrorHandler = e.DefaultHTTPErrorHandler | ||||
| 	e.Binder = &DefaultBinder{} | ||||
| 	e.Logger.SetLevel(glog.OFF) | ||||
| 	e.Logger.SetLevel(log.OFF) | ||||
| 	e.pool.New = func() interface{} { | ||||
| 		return e.NewContext(nil, nil) | ||||
| 	} | ||||
| @@ -271,24 +271,33 @@ func (e *Echo) Router() *Router { | ||||
| 	return e.router | ||||
| } | ||||
|  | ||||
| // DefaultHTTPErrorHandler invokes the default HTTP error handler. | ||||
| // DefaultHTTPErrorHandler is the default HTTP error handler. It sends a JSON response | ||||
| // with status code. | ||||
| func (e *Echo) DefaultHTTPErrorHandler(err error, c Context) { | ||||
| 	code := http.StatusInternalServerError | ||||
| 	msg := http.StatusText(code) | ||||
| 	var ( | ||||
| 		code = http.StatusInternalServerError | ||||
| 		msg  interface{} | ||||
| 	) | ||||
|  | ||||
| 	if he, ok := err.(*HTTPError); ok { | ||||
| 		code = he.Code | ||||
| 		msg = he.Message | ||||
| 	} else { | ||||
| 		msg = Map{"message": err} | ||||
| 	} | ||||
| 	if e.Debug { | ||||
| 		msg = err.Error() | ||||
| 	} | ||||
|  | ||||
| 	if !c.Response().Committed { | ||||
| 		if c.Request().Method == HEAD { // Issue #608 | ||||
| 			c.NoContent(code) | ||||
| 			if err := c.NoContent(code); err != nil { | ||||
| 				goto ERROR | ||||
| 			} | ||||
| 		} else { | ||||
| 			c.String(code, msg) | ||||
| 			if err := c.JSON(code, msg); err != nil { | ||||
| 				goto ERROR | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| ERROR: | ||||
| 	e.Logger.Error(err) | ||||
| } | ||||
|  | ||||
| @@ -545,7 +554,7 @@ func (e *Echo) StartServer(s *http.Server) error { | ||||
| 	gs := &graceful.Server{ | ||||
| 		Server:  s, | ||||
| 		Timeout: e.ShutdownTimeout, | ||||
| 		Logger:  log.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0), | ||||
| 		Logger:  slog.New(e.Logger.Output(), e.Logger.Prefix()+": ", 0), | ||||
| 	} | ||||
| 	if s.TLSConfig == nil { | ||||
| 		e.server = gs | ||||
| @@ -568,17 +577,17 @@ func (e *Echo) ShutdownTLS(timeout time.Duration) { | ||||
| } | ||||
|  | ||||
| // NewHTTPError creates a new HTTPError instance. | ||||
| func NewHTTPError(code int, msg ...interface{}) *HTTPError { | ||||
| 	he := &HTTPError{Code: code, Message: http.StatusText(code)} | ||||
| 	if len(msg) > 0 { | ||||
| 		he.Message = fmt.Sprint(msg...) | ||||
| func NewHTTPError(code int, message ...interface{}) *HTTPError { | ||||
| 	he := &HTTPError{Code: code, Message: Map{"message": http.StatusText(code)}} | ||||
| 	if len(message) > 0 { | ||||
| 		he.Message = message[0] | ||||
| 	} | ||||
| 	return he | ||||
| } | ||||
|  | ||||
| // Error makes it compatible with `error` interface. | ||||
| func (e *HTTPError) Error() string { | ||||
| 	return e.Message | ||||
| func (he *HTTPError) Error() string { | ||||
| 	return fmt.Sprintf("code=%d, message=%s", he.Code, he.Message) | ||||
| } | ||||
|  | ||||
| // WrapHandler wraps `http.Handler` into `echo.HandlerFunc`. | ||||
|   | ||||
| @@ -380,13 +380,6 @@ func TestEchoMethodNotAllowed(t *testing.T) { | ||||
| 	assert.Equal(t, http.StatusMethodNotAllowed, rec.Code) | ||||
| } | ||||
|  | ||||
| func TestEchoHTTPError(t *testing.T) { | ||||
| 	m := http.StatusText(http.StatusBadRequest) | ||||
| 	he := NewHTTPError(http.StatusBadRequest, m) | ||||
| 	assert.Equal(t, http.StatusBadRequest, he.Code) | ||||
| 	assert.Equal(t, m, he.Error()) | ||||
| } | ||||
|  | ||||
| func TestEchoContext(t *testing.T) { | ||||
| 	e := New() | ||||
| 	c := e.AcquireContext() | ||||
|   | ||||
| @@ -62,11 +62,11 @@ func TestGzipErrorReturned(t *testing.T) { | ||||
| 	e := echo.New() | ||||
| 	e.Use(Gzip()) | ||||
| 	e.GET("/", func(c echo.Context) error { | ||||
| 		return echo.NewHTTPError(http.StatusInternalServerError, "error") | ||||
| 		return echo.ErrNotFound | ||||
| 	}) | ||||
| 	req, _ := http.NewRequest(echo.GET, "/", nil) | ||||
| 	rec := httptest.NewRecorder() | ||||
| 	e.ServeHTTP(rec, req) | ||||
| 	assert.Equal(t, http.StatusNotFound, rec.Code) | ||||
| 	assert.Empty(t, rec.Header().Get(echo.HeaderContentEncoding)) | ||||
| 	assert.Equal(t, "error", rec.Body.String()) | ||||
| } | ||||
|   | ||||
| @@ -9,14 +9,15 @@ description = "Customizing Echo" | ||||
|  | ||||
| ## HTTP Error Handler | ||||
|  | ||||
| Default HTTP error handler rules: | ||||
| Default HTTP error handler sends an error as JSON with the following rules: | ||||
|  | ||||
| - If error is of type `Echo#HTTPError` it sends HTTP response with status code `HTTPError.Code` | ||||
| - If error is `Echo#HTTPError` it sends HTTP response with status code `HTTPError.Code` | ||||
| and message `HTTPError.Message`. | ||||
| - Else it sends `500 - Internal Server Error`. | ||||
| - If debug mode is enabled, it uses `error.Error()` as status message. | ||||
| - If error is `error` it sends HTTP response with status code `500 - Internal Server Error`  | ||||
| and message `error.Error()`. | ||||
| - It logs the error. | ||||
|  | ||||
| You can also set a custom HTTP error handler using `Echo#HTTPErrorHandler`. | ||||
| You can set a custom HTTP error handler using `Echo#HTTPErrorHandler`. | ||||
|  | ||||
| ## Debugging | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user