fault

package module
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2023 License: BSD-3-Clause Imports: 7 Imported by: 1

README

go-http-fault

Go package providing a net/http handler for logging errors and rendering them to the browser using custom templates.

Documentation

Go Reference

Example

import (
       "net/http"
       "html/template"
       "log"

       "github.com/sfomuseum/go-http-fault/v2"
)

// Create a custom HTTP handler specific to your application that accepts a `fault.FaultHandler` instance

func ExampleHandler(fault_handler http.Handler) http.Handler {

	fn := func(rsp http.ResponseWriter, req *http.Request) {

		// In your handler invoke some custom code that may return an error
		
		err := SomeOtherFunction(req)

		// If it does assign the error returned and a status code (not required to be an HTTP status code)
		// that will be used for logging errors
		
		if err != nil {
			fault.AssignError(req, err, http.StatusInternalServerError)
			fault_handler.ServeHTTP(rsp, req)
			return
		}

		rsp.Write([]byte("Hello world"))
		return
	}

	h := http.HandlerFunc(fn)
	return h, nil
}

func main() {

	// In your application's `main` routine create and `html/template` instance
	// and retrieve a template named "fault" (or whatever you choose)
	
     	t, _ := template.New("example").Parse(...)
        fault_t := t.Lookup("fault")

	// Create a custom `log.Logger` instance that will be used to record errors
	
	error_logger := log.Default()

	// Now pass both to `fault.TemplatedFaultHandler` which will return an `http.Handler`
	
	fault_handler, _ := fault.TemplatedFaultHandler(error_logger, fault_t)

	// And pass that to any other handlers where you need a consistent interface
	// for handling public-facing errors
	
	handler := ExampleHandler(fault_handler)

	mux.Handle("/", handler)

	http.ListenAndServer(":8080", mux)

If you need to pass custom variables to a custom template you will need to take a few more steps. First, define a callback function that conforms to fault.FaultHandlerVarsFunc. Although the method signature says these callback functions only need to return an interface{} in actual fact you'll need to return a) a struct b) a pointer to that struct and c) ensure that struct conforms to the fault.FaultHandlerVars struct. For example:

type CustomVars struct {
     SomeOtherVariable string
     fault.FaultHandlerVars     
}

var custom_vars_func := func() interface{} {

    return &CustomVars{
    	SomeOtherVariable: "Hello world",
    }	
}

Note that CustomVars will be assigned Status and Error properties, which are an int and and error respectively, at runtime. If you assign your own values they will be overwritten.

Next create a FaultHandlerOptions instance which references your custom variable callback function, a log.Logger instance for feedback and debugging and a html/template.Template instance to be rendered by the fault handler. For example:

logger := log.Default()

tpl := template.New("test")
tpl, _ := tpl.Parse(`{{ .SomeOtherVariable }} {{ .Status }}`)

opts := &fault.FaultHandlerOptions{
	Logger:   logger,
	Template: tpl,
	VarsFunc: custom_vars_func,
}

Finally create the fault handler using the FaultHandlerWithOptions method. For example:

handler := fault.FaultHandlerWithOptions(opts)

Documentation

Overview

package fault provides a net/http handler for logging errors and rendering them to the browser using custom templates.

Index

Constants

View Source
const ErrorKey string = "github.com/sfomuseum/go-http-fault#error"

ErrorKey is the name of the key for assigning `error` values to a `context.Context` instance.

View Source
const StatusKey string = "github.com/sfomuseum/go-http-fault#status"

StatusKey is the name of the key for assigning status code values to a `context.Context` instance.

Variables

This section is empty.

Functions

func AssignError

func AssignError(req *http.Request, err error, status int)

AssignError assigns 'err' and 'status' the `ErrorKey` and `StatusKey` values of 'req.Context' and updates 'req' in place.

func FaultHandler

func FaultHandler(l *log.Logger) http.Handler

FaultHandler returns a `http.Handler` instance for handling errors in a web application.

func FaultHandlerWithOptions added in v2.1.0

func FaultHandlerWithOptions(opts *FaultHandlerOptions) http.Handler

faultHandler returns a `http.Handler` for handling errors in a web application. It will retrieve and "public" and "private" errors that have been recorded and log them to 'l'. If 't is defined it will executed and passed the "public" error as a template variable.

func ImplementsFaultHandlerVars added in v2.1.0

func ImplementsFaultHandlerVars(vars interface{}) bool

ImplementsFaultHandlerVars returns a boolean value indicating whether 'vars' conforms to the required fields of the `FaultHandlerVars` struct type.

func RetrieveError

func RetrieveError(req *http.Request) (int, error)

RetrieveError returns the values of the `StatusKey` and `ErrorKey` values of 'req.Context'

func TemplatedFaultHandler

func TemplatedFaultHandler(l *log.Logger, t *template.Template) http.Handler

TemplatedFaultHandler returns a `http.Handler` instance for handling errors in a web application with a custom HTML template.

func TemplatedFaultHandlerWrapper

func TemplatedFaultHandlerWrapper(l *log.Logger, t *template.Template, h http.Handler) http.Handler

TemplatedFaultHandlerWrapper will return a middleware `http.Handler` that when invoked will serve 'h' and if the response status code is >= `http.StatusBadRequest` (300) will serve a new fault handler using 't' and 'l'.

Types

type FaultError

type FaultError interface {
	error
	// Public returns an `error` instance whose string value is considered safe for publishing in a public setting or context.
	Public() error
	// Private returns an `error` instance whose string value that may contain details not suitable for publishing in a public setting or context.
	Private() error
}

FaultError is an interface for providing custom public and private error messages.

type FaultHandlerOptions added in v2.1.0

type FaultHandlerOptions struct {
	// Logger is a custom `log.Logger` instance used for logging and feedback.
	Logger *log.Logger
	// Template is an optional `html/template.Template` to use for reporting errors.
	Template *template.Template
	// VarFunc is a `FaultHandlerVarsFunc` used to derive variables passed to templates. Required if `Template` is non-nil.
	VarsFunc FaultHandlerVarsFunc
}

FaultHandlerOptions is a struct containing configuration options for the `FaultHandlerWithOptions` method.

type FaultHandlerVars

type FaultHandlerVars struct {
	Status int
	Error  error
}

FaultHandlerVars are the minimal required variables that will be pass to a fault handler template. If you need to pass additional fields then you will need to create your handler using the the `FaultHandlerWithOptions` method specifying a custom `FaultHandlerVarsFunc` property.

type FaultHandlerVarsFunc added in v2.1.0

type FaultHandlerVarsFunc func() interface{}

FaultHandlerVarsFunc is a custom function that returns a pointer to a struct that conforms to the required fields of the `FaultHandlerVars` struct type.

type FaultWrapper

type FaultWrapper struct {
	// contains filtered or unexported fields
}

FaultWrapper is a struct to make assigning `TemplatedFaultHandlerWrapper` instances easier.

func NewFaultWrapper

func NewFaultWrapper(logger *log.Logger, template *template.Template) *FaultWrapper

NewFaultWrapper will create a new `FaultWrapper` instance.

func (*FaultWrapper) HandleWithMux

func (fw *FaultWrapper) HandleWithMux(mux *http.ServeMux, uri string, h http.Handler)

HandleWithMux will wrap 'h' in a new `TemplatedFaultHandlerWrapper` middleware handler and then assign it to 'mux' with pattern 'uri'.

type StatusWriter

type StatusWriter struct {
	http.ResponseWriter
	Status int
}

StatusWriter type adds a `Status` property to Go's `http.ResponseWriter` type.

func NewStatusWriter

func NewStatusWriter(w http.ResponseWriter) *StatusWriter

New shows setup for a middleware function. This could be a logging function or similar whereby you require access to the status code from `http.ResponseWriter`

		func MyMiddleware(h http.HandleFunc) http.HandlerFunc {
				return func(w http.ResponseWriter, r *http.Request) {
       			sw := status_writer.New(w) // Here we override http.ResponseWriter's `WriteHeader` function
					h(sw, r)
       			statusCode := sw.Status // Now work with the status code
   			}
		}

func (*StatusWriter) WriteHeader

func (w *StatusWriter) WriteHeader(status int)

WriteHeader override the http.ResponseWriter's `WriteHeader` method

Jump to

Keyboard shortcuts

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