Skip to content

Instantly share code, notes, and snippets.

@shibukawa
Last active September 28, 2018 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shibukawa/42a9dee400c2f8577b4a763bcb1a5e5f to your computer and use it in GitHub Desktop.
Save shibukawa/42a9dee400c2f8577b4a763bcb1a5e5f to your computer and use it in GitHub Desktop.
Every handle should have return statement

Basically, error handling code and regular code have different purpose/aspect. So splitting error handling code from regular code is just introducing some type of "goto" structure essentially.

I like handle/check work locally inside function and are resticted not to escape between functions unlike exception are good point. But I think this design proposal may create a very complicated structure。

If there is only one handle per scope ({ }), it is resonable, but there are many handles and/or have defers in same scope, make code difficult. If we have to control error handling finely, error handling code and regular code are mixed like bunch of if err != nil sentences.

My suggestion

Every handler should have return statement and only one handler works that are defined at last.

func CopyFile(src, dst string) error {
  // this handler works if os.Open, os.Create fail
	handle err {
		return fmt.Errorf("opening %s %s: %v", src, dst, err)
	}

	r := check os.Open(src)
	defer r.Close()

	w := check os.Create(dst)

  // this handler works if io.Copy, w.Close fail
  handle err {
		w.Close()
		os.Remove(dst)
		return fmt.Errorf("copying %s %s: %v", src, dst, err)
	}

	check io.Copy(w, r)
	check w.Close()
	return nil
}

It makes clear order between handler and defers and regular code:

  1. Regular success code executes
  2. Some regular code executes and fails
  3. If there are scope nests ({ }) and defers between failure function call and the last defined handler, defers execute.
  4. handle executes
  5. If there are other defers except step 3, they execute.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment