diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-20 14:34:42 +0000 |
commit | 9f46488805e86b1bc341ea1620b866016c2ce5ed (patch) | |
tree | f9748c7e287041e37d6da49e0a29c9511dc34768 /doc/development/go_guide | |
parent | dfc92d081ea0332d69c8aca2f0e745cb48ae5e6d (diff) | |
download | gitlab-ce-9f46488805e86b1bc341ea1620b866016c2ce5ed.tar.gz |
Add latest changes from gitlab-org/gitlab@13-0-stable-ee
Diffstat (limited to 'doc/development/go_guide')
-rw-r--r-- | doc/development/go_guide/index.md | 74 |
1 files changed, 66 insertions, 8 deletions
diff --git a/doc/development/go_guide/index.md b/doc/development/go_guide/index.md index c1dfb220df8..fe69a4205f8 100644 --- a/doc/development/go_guide/index.md +++ b/doc/development/go_guide/index.md @@ -63,15 +63,20 @@ file and ask your manager to review and merge. ```yaml projects: gitlab: reviewer go - gitlab-foss: reviewer go ``` ## Code style and format - Avoid global variables, even in packages. By doing so you will introduce side effects if the package is included multiple times. -- Use `go fmt` before committing ([Gofmt](https://golang.org/cmd/gofmt/) is a - tool that automatically formats Go source code). +- Use `goimports` before committing. + [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports) + is a tool that automatically formats Go source code using + [Gofmt](https://golang.org/cmd/gofmt/), in addition to formatting import lines, + adding missing ones and removing unreferenced ones. + + Most editors/IDEs will allow you to run commands before/after saving a file, you can set it + up to run `goimports` so that it's applied to every file when saving. - Place private methods below the first caller method in the source file. ### Automatic linting @@ -244,6 +249,59 @@ Programs handling a lot of IO or complex operations should always include [benchmarks](https://golang.org/pkg/testing/#hdr-Benchmarks), to ensure performance consistency over time. +## Error handling + +### Adding context + +Adding context before you return the error can be helpful, instead of +just returning the error. This allows developers to understand what the +program was trying to do when it entered the error state making it much +easier to debug. + +For example: + +```go +// Wrap the error +return nil, fmt.Errorf("get cache %s: %w", f.Name, err) + +// Just add context +return nil, fmt.Errorf("saving cache %s: %v", f.Name, err) +``` + +A few things to keep in mind when adding context: + +- Decide if you want to expose the underlying error + to the caller. If so, use `%w`, if not, you can use `%v`. +- Don't use words like `failed`, `error`, `didn't`. As it's an error, + the user already knows that something failed and this might lead to + having strings like `failed xx failed xx failed xx`. Explain _what_ + failed instead. +- Error strings should not be capitalized or end with punctuation or a + newline. You can use `golint` to check for this. + +### Naming + +- When using sentinel errors they should always be named like `ErrXxx`. +- When creating a new error type they should always be named like + `XxxError`. + +### Checking Error types + +- To check error equality don't use `==`. Use + [`errors.Is`](https://pkg.go.dev/errors?tab=doc#Is) instead (for Go + versions >= 1.13). +- To check if the error is of a certain type don't use type assertion, + use [`errors.As`](https://pkg.go.dev/errors?tab=doc#As) instead (for + Go versions >= 1.13). + +### References for working with errors + +- [Go 1.13 errors](https://blog.golang.org/go1.13-errors). +- [Programing with + errors](https://peter.bourgon.org/blog/2019/09/11/programming-with-errors.html). +- [Don’t just check errors, handle them + gracefully](https://dave.cheney.net/2016/04/27/dont-just-check-errors-handle-them-gracefully). + ## CLIs Every Go program is launched from the command line. @@ -368,13 +426,13 @@ Once you've picked a new Go version to use, the steps to update Omnibus and CNG are: - [Create a merge request in the CNG project](https://gitlab.com/gitlab-org/build/CNG/edit/master/ci_files/variables.yml?branch_name=update-go-version), - updating the `GO_VERSION` in `ci_files/variables.yml`. + updating the `GO_VERSION` in `ci_files/variables.yml`. - Create a merge request in the [`gitlab-omnibus-builder` project](https://gitlab.com/gitlab-org/gitlab-omnibus-builder), - updating every file in the `docker/` directory so the `GO_VERSION` is set - appropriately. [Here's an example](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/125/diffs). + updating every file in the `docker/` directory so the `GO_VERSION` is set + appropriately. [Here's an example](https://gitlab.com/gitlab-org/gitlab-omnibus-builder/-/merge_requests/125/diffs). - Tag a new release of `gitlab-omnibus-builder` containing the change. -- [Create a merge request in the `gitlab-omnibus` project](https://gitlab.com/gitlab-org/omnibus-gitlab/edit/master/.gitlab-ci.yml?branch_name=update-gitlab-omnibus-builder-version), - updating the `BUILDER_IMAGE_REVISION` to match the newly-created tag. +- [Create a merge request in the `omnibus-gitlab` project](https://gitlab.com/gitlab-org/omnibus-gitlab/edit/master/.gitlab-ci.yml?branch_name=update-gitlab-omnibus-builder-version), + updating the `BUILDER_IMAGE_REVISION` to match the newly-created tag. To reduce unnecessary differences between two distribution methods, Omnibus and CNG **should always use the same Go version**. |