package main import ( "github.com/kataras/iris/v12" // IMPORTANT, import this sub-package. // Note tht it does NOT break compatibility with the // standard "errors" package as the New, // Is, As, Unwrap functions are aliases to the standard package. "github.com/kataras/iris/v12/x/errors" ) // Optionally, register custom error codes. // // The default list of error code names: // errors.Cancelled // errors.Unknown // errors.InvalidArgument // errors.DeadlineExceeded // errors.NotFound // errors.AlreadyExists // errors.PermissionDenied // errors.Unauthenticated // errors.ResourceExhausted // errors.FailedPrecondition // errors.Aborted // errors.OutOfRange // errors.Unimplemented // errors.Internal // errors.Unavailable // errors.DataLoss var ( Custom = errors.E("CUSTOM_CANONICAL_ERROR_NAME", iris.StatusBadRequest) ) func main() { app := iris.New() // Custom error code name. app.Get("/custom", fireCustomErrorCodeName) // Send a simple 400 request with message and an error // or with more details and data. app.Post("/invalid_argument", fireInvalidArgument) // Compatibility with the iris.Problem type (and any other custom type). app.Get("/problem", fireErrorWithProblem) app.Listen(":8080") } func fireCustomErrorCodeName(ctx iris.Context) { Custom.Details(ctx, "message", "details with arguments: %s", "an argument") } func fireInvalidArgument(ctx iris.Context) { var req = struct { Username string `json:"username"` }{} if err := ctx.ReadJSON(&req); err != nil { errors.InvalidArgument.Err(ctx, err) return } ctx.WriteString(req.Username) // Other examples: errors.InvalidArgument/NotFound/Internal and e.t.c. // .Message(ctx, "message %s", "optional argument") // .Details(ctx, "message", "details %s", "optional details argument") // .Data(ctx, "message", anyTypeOfValue) // .DataWithDetails(ctx, "unable to read the body", "malformed json", iris.Map{"custom": "data of any type"}) // .Log(ctx, "message %s", "optional argument") // .LogErr(ctx, err) } func fireErrorWithProblem(ctx iris.Context) { myCondition := true if myCondition { problem := iris.NewProblem(). // The type URI, if relative it automatically convert to absolute. Type("/product-error"). // The title, if empty then it gets it from the status code. Title("Product validation problem"). // Any optional details. Detail("details about the product error"). // The status error code of the problem, can be optional here. // Status(iris.StatusBadRequest). // Any custom key-value pair. Key("product_name", "the product name") errors.InvalidArgument.Data(ctx, "unable to process the request", problem) return /* Prints to the client: { "http_error_code": { "canonical_name": "INVALID_ARGUMENT", "status": 400 }, "message": "unable to process the request", "data": { "detail": "details about the product error", "product_name": "the product name", "title": "Product validation problem", "type": "/product-error" } } */ } }