Nexus pattern

Nexus pattern

The word nexus is defined as "The means of connection between things linked in series". The pattern is useful in error handling sequential function calls.

Example CopyFile(from, to string)

Copying a file, if done all in one function, is unreadable due to multiple error checking and handling. With the nexus pattern you define a type fileIO struct with the error field. Each method must check the previous error and return if it is set without doing anything. This way all subsequent calls are no-operations.

The err field links operations.
Each method sets x.err before returning.
type fileIO struct {
	err error
}

func (x *fileIO) Open(filename string) (fh *os.File) {
	if x.err != nil {
		return
	}
	fh, x.err = os.Open(filename)
	return
}

func (x *fileIO) Create(filename string) (fh *os.File) {
	if x.err != nil {
		return
	}
	fh, x.err = os.Create(filename)
	return
}

func (x *fileIO) Close(w io.Closer) {
	if x.err != nil {
		return
	}
	x.err = w.Close()
}

func (x *fileIO) Copy(w io.WriteCloser, r io.Reader) (n int64) {
	if x.err != nil {
		return
	}
	n, x.err = io.Copy(w, r)
	if x.err != nil {
		w.Close()
	}
	return
}
With the fileIO nexus inplace the CopyFile function is readable and with only one error checking and handling needed.
func CopyFile(src, dst string) error {
	x := &fileIO{}
	r := x.Open(src)
	w := x.Create(dst)
	x.Copy(w, r)
	x.Close(w)
	if x.err != nil {
		os.Remove(dst)
	}
	r.Close()
	return x.err
}