Happy New Year To Everyone! 🎅

Today is my Birthday too ^_^
This commit is contained in:
Gerasimos (Makis) Maropoulos 2023-12-31 18:56:14 +02:00
parent 50faf05528
commit 56754ff5cc
No known key found for this signature in database
GPG Key ID: B9839E9CD30B7B6B
5 changed files with 178 additions and 3 deletions

View File

@ -23,10 +23,11 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
Changes apply to `main` branch.
- Add `x/errors.ReadPayload`, `ReadQuery`, `ReadPaginationOptions`, `Handle`, `HandleCreate`, `HandleCreateResponse`, `HandleUpdate` and `HandleDelete` package-level functions as helpers for common actions.
- Add `x/jsonx.GetSimpleDateRange(date, jsonx.WeekRange, time.Monday, time.Sunday)` which returns all dates between the given range and start/end weekday values for WeekRange.
- Add `x/timex.GetMonthDays` and `x/timex.GetMonthEnd` functions.
- Add `iris.CookieDomain` and `iris.CookieOverride` cookie options to handle [#2309](https://github.com/kataras/iris/issues/2309).
- New `x/errors.ErrorCodeName.MapErrorFunc`, `x/errors.ErrorCodeName.MapErrors`, `x/errors.ErrorCodeName.Wrap` methods and `x/errors.HandleError` package-level function.
- New `x/errors.ErrorCodeName.MapErrorFunc`, `MapErrors`, `Wrap` methods and `x/errors.HandleError` package-level function.
# Sun, 05 Nov 2023 | v12.2.8

View File

@ -1,6 +1,6 @@
BSD 3-Clause License
Copyright (c) 2016-2023, Gerasimos (Makis) Maropoulos
Copyright (c) 2016-2024, Gerasimos (Makis) Maropoulos
All rights reserved.
Redistribution and use in source and binary forms, with or without

View File

@ -4,6 +4,34 @@
Try the official [Iris Command Line Interface](https://github.com/kataras/iris-cli) today! -->
# 🎅 Happy new year to everyone!
```
A new year is here, full of hope and cheer
A time to celebrate, and appreciate
the past year's achievements, and the future's improvements.
We are proud to present, our open-source project
Iris web framework, a fast and elegant way to make
Web applications, with ease and satisfaction.
Iris is built with Go, a language you should know
It offers high performance, and great concurrency.
It has a rich ecosystem, and a friendly community.
Iris is designed to be, simple and flexible
It has a modular structure, and a powerful router.
It supports middleware, and many features.
Iris is more than a tool, it is a vision
To empower developers, and inspire creations
to make the web better, and brighter.
We thank you for your support, and your feedback.
We hope you enjoy using Iris, and find it useful.
We wish you a happy new year, and a successful career.
```
# <a href="https://iris-go.com"><img src="https://iris-go.com/images/logo-new-lq-45.png"></a> Iris Web Framework <a href="README_GR.md"><img width="20px" src="https://iris-go.com/images/flag-greece.svg" /> <a href="README_JA.md"><img width="20px" height="20px" src="https://iris-go.com/images/flag-japan.svg" /></a> </a> <a href="README_FR.md"><img width="20px" src="https://iris-go.com/images/flag-france.svg" /></a> <a href="README_ZH_HANT.md"><img width="20px" src="https://iris-go.com/images/flag-taiwan.svg" /></a> <a href="README_ZH_HANS.md"><img width="20px" src="https://iris-go.com/images/flag-china.svg" /></a> <a href="README_ES.md"><img width="20px" src="https://iris-go.com/images/flag-spain.png" /></a> <a href="README_FA.md"><img width="20px" src="https://iris-go.com/images/flag-iran.svg" /></a> <a href="README_RU.md"><img width="20px" src="https://iris-go.com/images/flag-russia.svg" /></a> <a href="README_KO.md"><img width="20px" src="https://iris-go.com/images/flag-south-korea.svg?v=12" /></a> <a href="README_PT_BR.md"><img width="20px" height="20px" src="https://iris-go.com/images/flag-brazil.svg" /></a> <a href="README_VN.md"><img width="20px" height="20px" src="https://iris-go.com/images/flag-vietnam.svg" /></a>
[![build status](https://img.shields.io/github/actions/workflow/status/kataras/iris/ci.yml?branch=main&style=for-the-badge)](https://github.com/kataras/iris/actions/workflows/ci.yml) [![view examples](https://img.shields.io/badge/examples%20-285-a83adf.svg?style=for-the-badge&logo=go)](https://github.com/kataras/iris/tree/main/_examples) [![chat](https://img.shields.io/gitter/room/iris_go/community.svg?color=cc2b5e&logo=gitter&style=for-the-badge)](https://gitter.im/iris_go/community) <!--[![FOSSA Status](https://img.shields.io/badge/LICENSE%20SCAN-PASSING❤-CD2956?style=for-the-badge&logo=fossa)](https://app.fossa.io/projects/git%2Bgithub.com%2Fkataras%2Firis?ref=badge_shield)--> [![donate](https://img.shields.io/badge/support-Iris-blue.svg?style=for-the-badge&logo=paypal)](https://iris-go.com/donate) <!--[![report card](https://img.shields.io/badge/report%20card-a%2B-ff3333.svg?style=for-the-badge)](https://goreportcard.com/report/github.com/kataras/iris)--><!--[![godocs](https://img.shields.io/badge/go-%20docs-488AC7.svg?style=for-the-badge)](https://pkg.go.dev/github.com/kataras/iris/v12@v12.2.8)--> <!-- [![release](https://img.shields.io/badge/release%20-v12.0-0077b3.svg?style=for-the-badge)](https://github.com/kataras/iris/releases) -->

View File

@ -59,7 +59,7 @@ var errorCodeMap = make(map[ErrorCodeName]ErrorCode)
// Example:
//
// var (
// NotFound = errors.E("NOT_FOUND", http.StatusNotFound)
// NotFound = errors.E("NOT_FOUND", http.StatusNotFound)
// )
// ...
// NotFound.Details(ctx, "resource not found", "user with id: %q was not found", userID)
@ -118,6 +118,7 @@ var (
)
// errorFuncCodeMap is a read-only map of error code names and their error functions.
// See HandleError package-level function.
var errorFuncCodeMap = make(map[ErrorCodeName][]func(error) error)
// HandleError handles an error by sending it to the client

145
x/errors/handlers.go Normal file
View File

@ -0,0 +1,145 @@
package errors
import (
"net/http"
"github.com/kataras/iris/v12/context"
"github.com/kataras/iris/v12/x/pagination"
)
// ReadPayload reads a JSON payload from the context and returns it as a generic type T.
// It also returns a boolean value indicating whether the read was successful or not.
// If the read fails, it sends an appropriate error response to the client.
func ReadPayload[T any](ctx *context.Context) (T, bool) {
var payload T
err := ctx.ReadJSON(&payload)
if err != nil {
if vErrs, ok := AsValidationErrors(err); ok {
InvalidArgument.Data(ctx, "validation failure", vErrs)
} else {
InvalidArgument.Details(ctx, "unable to parse body", err.Error())
}
return payload, false
}
return payload, true
}
// ReadQuery reads URL query values from the context and returns it as a generic type T.
// It also returns a boolean value indicating whether the read was successful or not.
// If the read fails, it sends an appropriate error response to the client.
func ReadQuery[T any](ctx *context.Context) (T, bool) {
var payload T
err := ctx.ReadQuery(&payload)
if err != nil {
if vErrs, ok := AsValidationErrors(err); ok {
InvalidArgument.Data(ctx, "validation failure", vErrs)
} else {
InvalidArgument.Details(ctx, "unable to parse query", err.Error())
}
return payload, false
}
return payload, true
}
// ReadPaginationOptions reads the ListOptions from the URL Query and
// any filter options of generic T from the request body.
func ReadPaginationOptions[T /* T is FilterOptions */ any](ctx *context.Context) (pagination.ListOptions, T, bool) {
list, ok := ReadQuery[pagination.ListOptions](ctx)
if !ok {
var t T
return list, t, false
}
filter, ok := ReadPayload[T](ctx)
if !ok {
var t T
return list, t, false
}
return list, filter, true
}
// Handle handles a generic response and error from a service call and sends a JSON response to the context.
// It returns a boolean value indicating whether the handle was successful or not.
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
func Handle(ctx *context.Context, resp interface{}, err error) bool {
if HandleError(ctx, err) {
return false
}
return ctx.JSON(resp) == nil
}
// IDPayload is a simple struct which describes a json id value.
type IDPayload struct {
ID string `json:"id"`
}
// HandleCreate handles a create operation and sends a JSON response with the created id to the client.
// It returns a boolean value indicating whether the handle was successful or not.
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
// If the id is not empty, it sets the status code to 201 (Created) and sends the id as a JSON payload.
func HandleCreate(ctx *context.Context, id string, err error) bool {
if HandleError(ctx, err) {
return false
}
ctx.StatusCode(http.StatusCreated)
if id != "" {
ctx.JSON(IDPayload{ID: id})
}
return true
}
// HandleCreateResponse handles a create operation and sends a JSON response with the created resource to the client.
// It returns a boolean value indicating whether the handle was successful or not.
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
// If the response is not nil, it sets the status code to 201 (Created) and sends the response as a JSON payload.
func HandleCreateResponse(ctx *context.Context, resp interface{}, err error) bool {
if HandleError(ctx, err) {
return false
}
ctx.StatusCode(http.StatusCreated)
if resp != nil {
return ctx.JSON(resp) == nil
}
return true
}
// HandleUpdate handles an update operation and sends a status code to the client.
// It returns a boolean value indicating whether the handle was successful or not.
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
// If the updated value is true, it sets the status code to 204 (No Content).
// If the updated value is false, it sets the status code to 304 (Not Modified).
func HandleUpdate(ctx *context.Context, updated bool, err error) bool {
if HandleError(ctx, err) {
return false
}
if updated {
ctx.StatusCode(http.StatusNoContent)
} else {
ctx.StatusCode(http.StatusNotModified)
}
return true
}
// HandleDelete handles a delete operation and sends a status code to the client.
// If the error is not nil, it calls HandleError to send an appropriate error response to the client.
// It sets the status code to 204 (No Content).
func HandleDelete(ctx *context.Context, err error) bool {
if HandleError(ctx, err) {
return false
}
ctx.StatusCode(http.StatusNoContent)
return true
}