mirror of
https://github.com/kataras/iris.git
synced 2025-12-22 12:27:02 +00:00
Version 3.0.0-beta cleaned
This commit is contained in:
228
httperror.go
Normal file
228
httperror.go
Normal file
@@ -0,0 +1,228 @@
|
||||
package iris
|
||||
|
||||
//taken from net/http
|
||||
const (
|
||||
StatusContinue = 100
|
||||
StatusSwitchingProtocols = 101
|
||||
|
||||
StatusOK = 200
|
||||
StatusCreated = 201
|
||||
StatusAccepted = 202
|
||||
StatusNonAuthoritativeInfo = 203
|
||||
StatusNoContent = 204
|
||||
StatusResetContent = 205
|
||||
StatusPartialContent = 206
|
||||
|
||||
StatusMultipleChoices = 300
|
||||
StatusMovedPermanently = 301
|
||||
StatusFound = 302
|
||||
StatusSeeOther = 303
|
||||
StatusNotModified = 304
|
||||
StatusUseProxy = 305
|
||||
StatusTemporaryRedirect = 307
|
||||
|
||||
StatusBadRequest = 400
|
||||
StatusUnauthorized = 401
|
||||
StatusPaymentRequired = 402
|
||||
StatusForbidden = 403
|
||||
StatusNotFound = 404
|
||||
StatusMethodNotAllowed = 405
|
||||
StatusNotAcceptable = 406
|
||||
StatusProxyAuthRequired = 407
|
||||
StatusRequestTimeout = 408
|
||||
StatusConflict = 409
|
||||
StatusGone = 410
|
||||
StatusLengthRequired = 411
|
||||
StatusPreconditionFailed = 412
|
||||
StatusRequestEntityTooLarge = 413
|
||||
StatusRequestURITooLong = 414
|
||||
StatusUnsupportedMediaType = 415
|
||||
StatusRequestedRangeNotSatisfiable = 416
|
||||
StatusExpectationFailed = 417
|
||||
StatusTeapot = 418
|
||||
StatusPreconditionRequired = 428
|
||||
StatusTooManyRequests = 429
|
||||
StatusRequestHeaderFieldsTooLarge = 431
|
||||
StatusUnavailableForLegalReasons = 451
|
||||
|
||||
StatusInternalServerError = 500
|
||||
StatusNotImplemented = 501
|
||||
StatusBadGateway = 502
|
||||
StatusServiceUnavailable = 503
|
||||
StatusGatewayTimeout = 504
|
||||
StatusHTTPVersionNotSupported = 505
|
||||
StatusNetworkAuthenticationRequired = 511
|
||||
)
|
||||
|
||||
var statusText = map[int]string{
|
||||
StatusContinue: "Continue",
|
||||
StatusSwitchingProtocols: "Switching Protocols",
|
||||
|
||||
StatusOK: "OK",
|
||||
StatusCreated: "Created",
|
||||
StatusAccepted: "Accepted",
|
||||
StatusNonAuthoritativeInfo: "Non-Authoritative Information",
|
||||
StatusNoContent: "No Content",
|
||||
StatusResetContent: "Reset Content",
|
||||
StatusPartialContent: "Partial Content",
|
||||
|
||||
StatusMultipleChoices: "Multiple Choices",
|
||||
StatusMovedPermanently: "Moved Permanently",
|
||||
StatusFound: "Found",
|
||||
StatusSeeOther: "See Other",
|
||||
StatusNotModified: "Not Modified",
|
||||
StatusUseProxy: "Use Proxy",
|
||||
StatusTemporaryRedirect: "Temporary Redirect",
|
||||
|
||||
StatusBadRequest: "Bad Request",
|
||||
StatusUnauthorized: "Unauthorized",
|
||||
StatusPaymentRequired: "Payment Required",
|
||||
StatusForbidden: "Forbidden",
|
||||
StatusNotFound: "Not Found",
|
||||
StatusMethodNotAllowed: "Method Not Allowed",
|
||||
StatusNotAcceptable: "Not Acceptable",
|
||||
StatusProxyAuthRequired: "Proxy Authentication Required",
|
||||
StatusRequestTimeout: "Request Timeout",
|
||||
StatusConflict: "Conflict",
|
||||
StatusGone: "Gone",
|
||||
StatusLengthRequired: "Length Required",
|
||||
StatusPreconditionFailed: "Precondition Failed",
|
||||
StatusRequestEntityTooLarge: "Request Entity Too Large",
|
||||
StatusRequestURITooLong: "Request URI Too Long",
|
||||
StatusUnsupportedMediaType: "Unsupported Media Type",
|
||||
StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
|
||||
StatusExpectationFailed: "Expectation Failed",
|
||||
StatusTeapot: "I'm a teapot",
|
||||
StatusPreconditionRequired: "Precondition Required",
|
||||
StatusTooManyRequests: "Too Many Requests",
|
||||
StatusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large",
|
||||
StatusUnavailableForLegalReasons: "Unavailable For Legal Reasons",
|
||||
|
||||
StatusInternalServerError: "Internal Server Error",
|
||||
StatusNotImplemented: "Not Implemented",
|
||||
StatusBadGateway: "Bad Gateway",
|
||||
StatusServiceUnavailable: "Service Unavailable",
|
||||
StatusGatewayTimeout: "Gateway Timeout",
|
||||
StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
|
||||
StatusNetworkAuthenticationRequired: "Network Authentication Required",
|
||||
}
|
||||
|
||||
// StatusText returns a text for the HTTP status code. It returns the empty
|
||||
// string if the code is unknown.
|
||||
func StatusText(code int) string {
|
||||
return statusText[code]
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
type (
|
||||
|
||||
// HTTPErrorHandler is just an object which stores a http status code and a handler
|
||||
HTTPErrorHandler struct {
|
||||
code int
|
||||
handler HandlerFunc
|
||||
}
|
||||
|
||||
// HTTPErrorContainer is the struct which contains the handlers which will execute if http error occurs
|
||||
// One struct per Server instance, the meaning of this is that the developer can change the default error message and replace them with his/her own completely custom handlers
|
||||
//
|
||||
// Example of usage:
|
||||
// iris.OnError(405, func (ctx *iris.Context){ c.SendStatus(405,"Method not allowed!!!")})
|
||||
// and inside the handler which you have access to the current Context:
|
||||
// ctx.EmitError(405)
|
||||
HTTPErrorContainer struct {
|
||||
// Errors contains all the httperrorhandlers
|
||||
Errors []*HTTPErrorHandler
|
||||
}
|
||||
)
|
||||
|
||||
// HTTPErrorHandlerFunc creates a handler which is responsible to send a particular error to the client
|
||||
func HTTPErrorHandlerFunc(statusCode int, message string) HandlerFunc {
|
||||
return func(ctx *Context) {
|
||||
ctx.SetStatusCode(statusCode)
|
||||
ctx.SetBodyString(message)
|
||||
}
|
||||
}
|
||||
|
||||
// GetCode returns the http status code value
|
||||
func (e *HTTPErrorHandler) GetCode() int {
|
||||
return e.code
|
||||
}
|
||||
|
||||
// GetHandler returns the handler which is type of HandlerFunc
|
||||
func (e *HTTPErrorHandler) GetHandler() HandlerFunc {
|
||||
return e.handler
|
||||
}
|
||||
|
||||
// SetHandler sets the handler (type of HandlerFunc) to this particular ErrorHandler
|
||||
func (e *HTTPErrorHandler) SetHandler(h HandlerFunc) {
|
||||
e.handler = h
|
||||
}
|
||||
|
||||
// defaultHTTPErrors creates and returns an instance of HTTPErrorContainer with default handlers
|
||||
func defaultHTTPErrors() *HTTPErrorContainer {
|
||||
httperrors := new(HTTPErrorContainer)
|
||||
httperrors.Errors = make([]*HTTPErrorHandler, 0)
|
||||
httperrors.OnError(StatusNotFound, HTTPErrorHandlerFunc(StatusNotFound, statusText[StatusNotFound]))
|
||||
httperrors.OnError(StatusInternalServerError, HTTPErrorHandlerFunc(StatusInternalServerError, statusText[StatusInternalServerError]))
|
||||
return httperrors
|
||||
}
|
||||
|
||||
// GetByCode returns the error handler by it's http status code
|
||||
func (he *HTTPErrorContainer) GetByCode(httpStatus int) *HTTPErrorHandler {
|
||||
if he != nil {
|
||||
for _, h := range he.Errors {
|
||||
if h.GetCode() == httpStatus {
|
||||
return h
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnError Registers a handler for a specific http error status
|
||||
func (he *HTTPErrorContainer) OnError(httpStatus int, handler HandlerFunc) {
|
||||
if httpStatus == StatusOK {
|
||||
return
|
||||
}
|
||||
|
||||
if errH := he.GetByCode(httpStatus); errH != nil {
|
||||
|
||||
errH.SetHandler(handler)
|
||||
} else {
|
||||
he.Errors = append(he.Errors, &HTTPErrorHandler{code: httpStatus, handler: handler})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///TODO: the errors must have .Next too, as middlewares inside the Context, if I let it as it is then we have problem
|
||||
// we cannot set a logger and a custom handler at one error because now the error handler takes only one handelrFunc and executes there from here...
|
||||
|
||||
// EmitError executes the handler of the given error http status code
|
||||
func (he *HTTPErrorContainer) EmitError(errCode int, ctx *Context) {
|
||||
|
||||
if errHandler := he.GetByCode(errCode); errHandler != nil {
|
||||
ctx.SetStatusCode(errCode) // for any case, user can change it after if want to
|
||||
errHandler.GetHandler().Serve(ctx)
|
||||
} else {
|
||||
//if no error is registed, then register it with the default http error text, and re-run the Emit
|
||||
he.OnError(errCode, func(c *Context) {
|
||||
c.SetStatusCode(errCode)
|
||||
c.SetBodyString(StatusText(errCode))
|
||||
})
|
||||
he.EmitError(errCode, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// OnNotFound sets the handler for http status 404,
|
||||
// default is a response with text: 'Not Found' and status: 404
|
||||
func (he *HTTPErrorContainer) OnNotFound(handlerFunc HandlerFunc) {
|
||||
he.OnError(StatusNotFound, handlerFunc)
|
||||
}
|
||||
|
||||
// OnPanic sets the handler for http status 500,
|
||||
// default is a response with text: The server encountered an unexpected condition which prevented it from fulfilling the request. and status: 500
|
||||
func (he *HTTPErrorContainer) OnPanic(handlerFunc HandlerFunc) {
|
||||
he.OnError(StatusInternalServerError, handlerFunc)
|
||||
}
|
||||
Reference in New Issue
Block a user