ginutil

package
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 30, 2021 License: MIT Imports: 11 Imported by: 4

Documentation

Index

Examples

Constants

This section is empty.

Variables

View Source
var DefaultLoggerHandler = LoggerWithConfig(LoggerConfig{
	Level: logger.LevelDebug,
})

DefaultLoggerHandler is a Gin-compatible logger that uses wharf-core logging.

View Source
var DefaultLoggerWriter = NewLoggerWriter(logger.NewScoped("GIN-debug"), logger.LevelDebug)

DefaultLoggerWriter is an io.Writer that logs all written messages using appropriate logging levels on a logger with the scope "GIN-debug".

Any [GIN-debug] messages are trimmed away.

Any messages starting with [WARNING] or [ERROR] are logged with the appropriate logging levels, and any other logs will use debug logging.

RecoverProblem is a Gin middleware that uses RecoverProblemHandle.

Functions

func LoggerWithConfig

func LoggerWithConfig(config LoggerConfig) gin.HandlerFunc

LoggerWithConfig creates a Gin middleware handler function that logs all requests using the logging level from the config.

If the logger implementation inside the config is unset, then it defaults to a new scoped logger with the scope "GIN".

func NewLoggerWriter

func NewLoggerWriter(log logger.Logger, defaultLevel logger.Level) io.Writer

NewLoggerWriter creates a logger that channels everything written to it via a wharf-core logger.

Any [GIN-debug] messages are trimmed away.

Any messages starting with [WARNING] or [ERROR] are logged with the appropriate logging levels, and any other logs will use the default logging level provided to this function.

func ParseParamInt

func ParseParamInt(c *gin.Context, paramName string) (int, bool)

ParseParamInt tries to read the named path parameter from the request and parse it to an int.

If it fails, it will write out a problem response using WriteProblemError with the status code 400 (Bad Request).

func ParseParamUint

func ParseParamUint(c *gin.Context, paramName string) (uint, bool)

ParseParamUint tries to read the named path parameter from the request and parse it to an uint.

If it fails, it will write out a problem response using WriteProblemError with the status code 400 (Bad Request).

func ParseQueryInt

func ParseQueryInt(c *gin.Context, queryName string) (int, bool)

ParseQueryInt tries to read the named query parameter from the request and parse it to an int.

If it fails, it will write out a problem response using WriteProblemError with the status code 400 (Bad Request).

func ParseQueryUint

func ParseQueryUint(c *gin.Context, queryName string) (uint, bool)

ParseQueryUint tries to read the named query parameter from the request and parse it to an uint.

If it fails, it will write out a problem response using WriteProblemError with the status code 400 (Bad Request).

func RecoverProblemHandle

func RecoverProblemHandle(c *gin.Context, err interface{})

RecoverProblemHandle writes a HTTP "Internal Server Error" problem response. Meant to be used with the gin-gonic panic recover middleware.

Example
package main

import (
	"github.com/gin-gonic/gin"
	"github.com/iver-wharf/wharf-core/pkg/ginutil"
)

func main() {
	r := gin.New()

	r.Use(
		gin.CustomRecovery(ginutil.RecoverProblemHandle),
	)
}
Output:

func RequireParamString

func RequireParamString(c *gin.Context, paramName string) (string, bool)

RequireParamString tries to read the named path parameter from the request and checks that it's not empty.

If it fails, it will write out a problem response using WriteProblem with the status code 400 (Bad Request).

func RequireQueryString

func RequireQueryString(c *gin.Context, queryName string) (string, bool)

RequireQueryString tries to read the named query parameter from the request and checks that it's not empty.

If it fails, it will write out a problem response using WriteProblem with the status code 400 (Bad Request).

func WriteAPIClientReadError

func WriteAPIClientReadError(c *gin.Context, err error, detail string)

WriteAPIClientReadError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/api-client/unexpected-read-error".

Meant to be used on unexpected error when reading data using the Wharf API.

func WriteAPIClientWriteError

func WriteAPIClientWriteError(c *gin.Context, err error, detail string)

WriteAPIClientWriteError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/api-client/unexpected-write-error".

Meant to be used on unexpected error when writing data using the Wharf API.

func WriteBodyReadError

func WriteBodyReadError(c *gin.Context, err error, detail string)

WriteBodyReadError uses WriteProblemError to write a 400 "Bad Request" response with the type "/prob/api/unexpected-body-read-error".

Meant to be used on unexpected error when reading the raw HTTP request body.

func WriteComposingProviderDataError

func WriteComposingProviderDataError(c *gin.Context, err error, detail string)

WriteComposingProviderDataError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/provider/composing-provider-data".

Meant to be used by the provider plugins on error when composing the provider object to submit to the Wharf API, such as when it fails to parse URLs received from the remote provider.

func WriteDBNotFound

func WriteDBNotFound(c *gin.Context, detail string)

WriteDBNotFound uses WriteProblem to write a 404 "Not Found" response with the type "/prob/api/record-not-found".

Meant to be used when fetching a specific item from the database but it was not found so this response is returned instead.

func WriteDBReadError

func WriteDBReadError(c *gin.Context, err error, detail string)

WriteDBReadError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/api/unexpected-db-read-error".

Meant to be used on unexpected error responses when doing a SELECT or other read operation towards the database.

func WriteDBWriteError

func WriteDBWriteError(c *gin.Context, err error, detail string)

WriteDBWriteError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/api/unexpected-db-write-error".

Meant to be used on unexpected error responses when doing a CREATE, UPDATE or other write operation towards the database.

func WriteFetchBuildDefinitionError

func WriteFetchBuildDefinitionError(c *gin.Context, err error, detail string)

WriteFetchBuildDefinitionError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/provider/fetch-build-definition".

Meant to be used on error when the provider plugin fails to fetch the build definition from the remote provider.

func WriteInvalidBindError

func WriteInvalidBindError(c *gin.Context, err error, detail string)

WriteInvalidBindError uses WriteProblemError to write a 400 "Bad Request" response with the type "/prob/api/invalid-param".

Meant to be used when binding parameters in an endpoint handler.

func WriteInvalidParamError

func WriteInvalidParamError(c *gin.Context, err error, paramName, detail string)

WriteInvalidParamError uses WriteProblemError to write a 400 "Bad Request" response with the type "/prob/api/invalid-param".

Meant to be used when parsing parameters in an endpoint handler.

func WriteMultipartFormReadError

func WriteMultipartFormReadError(c *gin.Context, err error, detail string)

WriteMultipartFormReadError uses WriteProblemError to write a 400 "Bad Request" response with the type "/prob/api/unexpected-multipart-read-error".

Meant to be used on unexpected error when reading a multipart/form-data request using gin.Context.MultipartForm().

func WriteProblem

func WriteProblem(c *gin.Context, prob problem.Response)

WriteProblem writes the Problem as JSON into the output response body together with appropriate Content-Type header.

Problem.Type is set to "about:blank" (as recommended by the IETF RFC-7808) if left unset, or converts scheme-less URIs to start with "https://iver-wharf.github.io/#/".

Problem.Status is set to 500 (Internal Server Error) if left unset.

Problem.Instance is set to the request URI from the gorm.Context if left unset.

Problem.Title is set to "Unknown error." if left unset.

Problem.Detail is unaltered.

Problem.Errors is set to the errors set to gin.Context.Errors if left empty.

Example
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"

	"github.com/gin-gonic/gin"
	"github.com/iver-wharf/wharf-core/pkg/ginutil"
	"github.com/iver-wharf/wharf-core/pkg/problem"
)

func init() {
	gin.SetMode(gin.ReleaseMode)
}

func indentedBodyFromResponse(resp *http.Response) string {
	body, _ := io.ReadAll(resp.Body)
	var indentedBodyBuff bytes.Buffer
	json.Indent(&indentedBodyBuff, body, "", "  ")
	return indentedBodyBuff.String()
}

func main() {
	var prob = problem.Response{
		Type:     "https://iver-wharf.github.io/#/prob/build/run/invalid-input",
		Title:    "Invalid input variable for build.",
		Status:   400,
		Detail:   "Build requires input variable 'myInput' to be of type 'string', but got 'int' instead.",
		Instance: "/projects/12345/builds/run/6789",
		Errors: []string{
			"strconv.ParseUint: parsing \"-1\": invalid syntax",
		},
	}

	w := httptest.NewRecorder()
	c, _ := gin.CreateTestContext(w)

	ginutil.WriteProblem(c, prob)

	resp := w.Result()

	fmt.Println("HTTP/1.1", resp.Status)
	fmt.Println("Content-Type:", resp.Header.Get("Content-Type"))
	fmt.Println()
	fmt.Println(indentedBodyFromResponse(resp))

}
Output:

HTTP/1.1 400 Bad Request
Content-Type: application/problem+json

{
  "type": "https://iver-wharf.github.io/#/prob/build/run/invalid-input",
  "title": "Invalid input variable for build.",
  "status": 400,
  "detail": "Build requires input variable 'myInput' to be of type 'string', but got 'int' instead.",
  "instance": "/projects/12345/builds/run/6789",
  "errors": [
    "strconv.ParseUint: parsing \"-1\": invalid syntax"
  ]
}

func WriteProblemError

func WriteProblemError(c *gin.Context, err error, prob problem.Response)

WriteProblemError is a shorthand for adding an error via gin.Context.Error and writing the problem using WriteProblem.

func WriteProviderResponseError

func WriteProviderResponseError(c *gin.Context, err error, detail string)

WriteProviderResponseError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/provider/unexpected-response-format".

Meant to be used on unexpected error when a provider plugin fails to parse or interpret a response from the remote provider.

func WriteTriggerError

func WriteTriggerError(c *gin.Context, err error, detail string)

WriteTriggerError uses WriteProblemError to write a 502 "Bad Gateway" response with the type "/prob/api-client/unexpected-trigger-error".

Meant to be used when unexpectedly failing to trigger a new build indirectly from a Wharf API client, such as from a Wharf provider plugin.

func WriteUnauthorized

func WriteUnauthorized(c *gin.Context, detail string)

WriteUnauthorized uses WriteProblem to write a 401 "Unauthorized" response with the type "/prob/api/unauthorized".

Meant to be used for failed authentication.

func WriteUnauthorizedError

func WriteUnauthorizedError(c *gin.Context, err error, detail string)

WriteUnauthorizedError uses WriteProblemError to write a 401 "Unauthorized" response with the type "/prob/api/unauthorized".

Meant to be used for failed authentication.

Types

type LoggerConfig

type LoggerConfig struct {
	// Level is the logging level that each log message uses. Defaults to the
	// zero value of logger.Level, which is logger.LevelDebug.
	Level logger.Level
	// Logger is the logger implementation used when logging.
	Logger logger.Logger
	// OmitClientIP leaves out the client IP address that issued the web request
	// from the logs when set to true.
	OmitClientIP bool
	// OmitLatency leaves out the server cost in time for processing a request
	// from the logs when set to true.
	OmitLatency bool
	// OmitMethod leaves out the HTTP method (GET, POST, DELETE, HEAD, etc.)
	// that was used in the web request from the logs when set to true.
	OmitMethod bool
	// OmitPath leaves out the web request path (the URL without the protocol,
	// hostname, query parameters, and such) from the logs when set to true.
	OmitPath bool
	// OmitStatus leaves out the HTTP status (200 OK, 404 Not Found, etc.) of
	// the web response from the logs when set to true.
	OmitStatus bool
	// OmitError leaves out any Go errors that were thrown when processing the
	// web request from the logs when set to true.
	OmitError bool
	// SkipPaths is a url path array which logs are not written. Useful for
	// disabling logs issued by health checks.
	SkipPaths []string
}

LoggerConfig holds configuration for the Gin logging integration.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL