mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
parent
3574816e1d
commit
c8ed26ee51
|
@ -438,6 +438,7 @@ New Package-level Variables:
|
|||
|
||||
New Context Methods:
|
||||
|
||||
- `Context.SetErr(error)` and `Context.GetErr() error` helpers
|
||||
- `Context.Compress(bool) error` and `Context.CompressReader(bool) error`
|
||||
- `Context.Clone() Context` returns a copy of the Context.
|
||||
- `Context.IsCanceled() bool` reports whether the request has been canceled by the client.
|
||||
|
|
File diff suppressed because it is too large
Load Diff
2
cli.go
2
cli.go
|
@ -2,7 +2,7 @@ package iris
|
|||
|
||||
// +------------------------------------------------------------+
|
||||
// | Bridge code between iris-cli and iris web application |
|
||||
// | https://github.com/kataras/iris-cli |
|
||||
// | https://github.com/kataras/iris-cli |
|
||||
// +------------------------------------------------------------+
|
||||
|
||||
import (
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/andybalholm/brotli"
|
||||
"github.com/klauspost/compress/flate"
|
||||
"github.com/klauspost/compress/gzip"
|
||||
"github.com/klauspost/compress/s2"
|
||||
"github.com/klauspost/compress/s2" // snappy output but likely faster decompression.
|
||||
"github.com/klauspost/compress/snappy"
|
||||
)
|
||||
|
||||
|
@ -184,11 +184,10 @@ func AcquireCompressResponseWriter(w ResponseWriter, r *http.Request, level int)
|
|||
return nil, ErrResponseNotCompressed
|
||||
}
|
||||
|
||||
encoding := negotiateAcceptHeader(acceptEncoding, []string{"gzip", "deflate", "br", "snappy", "s2"}, "")
|
||||
encoding := negotiateAcceptHeader(acceptEncoding, []string{GZIP, DEFLATE, BROTLI, SNAPPY, S2}, IDENTITY)
|
||||
if encoding == "" {
|
||||
return nil, fmt.Errorf("%w: %s", ErrNotSupportedCompression, encoding)
|
||||
}
|
||||
AddCompressHeaders(w.Header(), encoding)
|
||||
|
||||
v := compressWritersPool.Get().(*CompressResponseWriter)
|
||||
v.ResponseWriter = w
|
||||
|
@ -212,6 +211,8 @@ func AcquireCompressResponseWriter(w ResponseWriter, r *http.Request, level int)
|
|||
}
|
||||
|
||||
v.CompressWriter = encWriter
|
||||
|
||||
AddCompressHeaders(w.Header(), encoding)
|
||||
return v, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -4505,6 +4505,32 @@ func (ctx *Context) Application() Application {
|
|||
return ctx.app
|
||||
}
|
||||
|
||||
const errorContextKey = "iris.context.error"
|
||||
|
||||
// SetErr is just a helper that sets an error value
|
||||
// as a context value, it does nothing more.
|
||||
// Also, by-default this error's value is written to the client
|
||||
// on failures when no registered error handler is available (see `Party.On(Any)ErrorCode`).
|
||||
// See `GetError` to retrieve it back.
|
||||
//
|
||||
// Note that, if you want to stop the chain
|
||||
// with an error see the `StopWithError` instead.
|
||||
func (ctx *Context) SetErr(err error) {
|
||||
ctx.Values().Set(errorContextKey, err)
|
||||
}
|
||||
|
||||
// GetErr is a helper which retrieves
|
||||
// the error value stored by `SetErr`.
|
||||
func (ctx *Context) GetErr() error {
|
||||
if v := ctx.Values().Get(errorContextKey); v != nil {
|
||||
if err, ok := v.(error); ok {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const idContextKey = "iris.context.id"
|
||||
|
||||
// SetID sets an ID, any value, to the Request Context.
|
||||
|
|
|
@ -548,8 +548,14 @@ func (h *routerHandler) FireErrorCode(ctx *context.Context) {
|
|||
break
|
||||
}
|
||||
|
||||
// not error handler found, write a default message.
|
||||
ctx.WriteString(context.StatusText(statusCode))
|
||||
// not error handler found,
|
||||
// see if failed with a stored error, and if so
|
||||
// then render it, otherwise write a default message.
|
||||
if err := ctx.GetErr(); err != nil {
|
||||
ctx.WriteString(err.Error())
|
||||
} else {
|
||||
ctx.WriteString(context.StatusText(statusCode))
|
||||
}
|
||||
}
|
||||
|
||||
func (h *routerHandler) subdomainAndPathAndMethodExists(ctx *context.Context, t *trie, method, path string) bool {
|
||||
|
|
|
@ -114,14 +114,23 @@ type compatibleErr interface {
|
|||
Error() string
|
||||
}
|
||||
|
||||
// dispatchErr writes the error to the response.
|
||||
// dispatchErr sets the error status code
|
||||
// and the error value to the context.
|
||||
// The APIBuilder's On(Any)ErrorCode is responsible to render this error code.
|
||||
func dispatchErr(ctx *context.Context, status int, err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
ctx.StatusCode(status)
|
||||
DefaultErrorHandler.HandleError(ctx, err)
|
||||
if err != ErrStopExecution {
|
||||
if status == 0 || !context.StatusCodeNotSuccessful(status) {
|
||||
status = DefaultErrStatusCode
|
||||
}
|
||||
|
||||
ctx.StatusCode(status)
|
||||
}
|
||||
|
||||
ctx.SetErr(err)
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -258,3 +258,24 @@ func TestPreflightResult(t *testing.T) {
|
|||
e.POST("/alternative").WithJSON(testInput{expected4.Name}).
|
||||
Expect().Status(httptest.StatusAccepted).JSON().Equal(expected4)
|
||||
}
|
||||
|
||||
func TestResponseErr(t *testing.T) {
|
||||
app := iris.New()
|
||||
var expectedErr = errors.New("response error")
|
||||
|
||||
app.OnAnyErrorCode(func(ctx iris.Context) {
|
||||
err := ctx.GetErr()
|
||||
if err != expectedErr {
|
||||
t.Fatalf("expected error value does not match")
|
||||
}
|
||||
|
||||
ctx.WriteString(err.Error())
|
||||
})
|
||||
|
||||
app.ConfigureContainer().Get("/", func() Response {
|
||||
return Response{Code: iris.StatusBadGateway, Err: expectedErr}
|
||||
})
|
||||
|
||||
e := httptest.New(t, app)
|
||||
e.GET("/").Expect().Status(iris.StatusBadGateway).Body().Equal("response error")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user