From 5d452bb582e6a9e3b893424ec135d0cbdf875659 Mon Sep 17 00:00:00 2001 From: aeneasr <3372410+aeneasr@users.noreply.github.com> Date: Fri, 31 Jul 2020 11:11:44 +0200 Subject: [PATCH] feat: add stub errors to errorx Closes #610 --- .../self-service/flows/user-facing-errors.md | 15 ++++++++++++++- selfservice/errorx/handler.go | 18 +++++++++++++++++- selfservice/errorx/handler_test.go | 16 ++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/docs/self-service/flows/user-facing-errors.md b/docs/docs/self-service/flows/user-facing-errors.md index 6040afa3701..4e6eb11ca3f 100644 --- a/docs/docs/self-service/flows/user-facing-errors.md +++ b/docs/docs/self-service/flows/user-facing-errors.md @@ -19,7 +19,7 @@ Assuming `selfservice.flows.error.ui_url` is set to The route matching `https://example.org/errors` uses the `error` URL Query parameter value `abcde` to make a request to ORY Kratos' Public or Admin API -`https://kratos-/self-service/errors?error=abcde`. The JSON Response contains a list of errors and their details, for example: ```json @@ -48,3 +48,16 @@ layouts. In general, errors have the following keys defined: When a user-facing error occurs and the HTTP client is an API Client (e.g. Mobile App), the error will be returned as the HTTP Response. No additional steps are required. + +## Using Stub Errors + +The error endpoint supports stub errors which can be used to implement your +Error UI: + +- `?error=stub:500` - returns a stub 500 (Internal Server Error) error. + +To call a stub error, simply do: + +```shell script +$ curl 'https://kratos-/self-service/errors?error=stub:500' +``` diff --git a/selfservice/errorx/handler.go b/selfservice/errorx/handler.go index c277376ead5..69990eb3105 100644 --- a/selfservice/errorx/handler.go +++ b/selfservice/errorx/handler.go @@ -1,17 +1,22 @@ package errorx import ( + "encoding/json" "net/http" "github.com/julienschmidt/httprouter" "github.com/justinas/nosurf" "github.com/pkg/errors" + "github.com/ory/herodot" + "github.com/ory/kratos/x" ) const ErrorsPath = "/self-service/errors" +var stub500, _ = json.Marshal([]interface{}{herodot.ErrInternalServerError.WithReasonf("This is a stub error.")}) + type ( handlerDependencies interface { x.WriterProvider @@ -69,6 +74,10 @@ type errorContainerParameters struct { // When accessing this endpoint through ORY Kratos' Public API, ensure that cookies are set as they are required for CSRF to work. To prevent // token scanning attacks, the public endpoint does not return 404 status codes. // +// This endpoint supports stub values to help you implement the error UI: +// +// - `?error=stub:500` - returns a stub 500 (Internal Server Error) error. +// // More information can be found at [ORY Kratos User User Facing Error Documentation](https://www.ory.sh/docs/kratos/self-service/flows/user-facing-errors). // // Produces: @@ -96,7 +105,14 @@ func (h *Handler) adminFetchError(w http.ResponseWriter, r *http.Request, ps htt } func (h *Handler) fetchError(w http.ResponseWriter, r *http.Request, mustVerify bool) error { - es, err := h.r.SelfServiceErrorPersister().Read(r.Context(), x.ParseUUID(r.URL.Query().Get("error"))) + id := r.URL.Query().Get("error") + switch id { + case "stub:500": + h.r.Writer().Write(w, r, &ErrorContainer{ID: x.NewUUID(), Errors: stub500}) + return nil + } + + es, err := h.r.SelfServiceErrorPersister().Read(r.Context(), x.ParseUUID(id)) if err != nil { return err } diff --git a/selfservice/errorx/handler_test.go b/selfservice/errorx/handler_test.go index d970369cc5f..93eb584098a 100644 --- a/selfservice/errorx/handler_test.go +++ b/selfservice/errorx/handler_test.go @@ -85,6 +85,22 @@ func TestHandler(t *testing.T) { }) }) + t.Run("case=stubs", func(t *testing.T) { + router := x.NewRouterAdmin() + h.RegisterAdminRoutes(router) + ts := httptest.NewServer(router) + defer ts.Close() + + res, err := ts.Client().Get(ts.URL + errorx.ErrorsPath + "?error=stub:500") + require.NoError(t, err) + require.EqualValues(t, http.StatusOK, res.StatusCode) + + actual, err := ioutil.ReadAll(res.Body) + require.NoError(t, err) + + assert.EqualValues(t, "This is a stub error.", gjson.GetBytes(actual, "errors.0.reason").String()) + }) + t.Run("case=errors types", func(t *testing.T) { router := x.NewRouterAdmin() h.RegisterAdminRoutes(router)