{"id":42274208,"url":"https://github.com/stackus/errors","last_synced_at":"2026-01-27T07:38:10.176Z","repository":{"id":50785497,"uuid":"369727954","full_name":"stackus/errors","owner":"stackus","description":"Builds on Go 1.13 errors by adding HTTP statuses and GRPC codes to them.","archived":false,"fork":false,"pushed_at":"2025-05-07T03:40:15.000Z","size":84,"stargazers_count":7,"open_issues_count":0,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-07T04:29:49.670Z","etag":null,"topics":["error-handling","errors","golang","grpc","http"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stackus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-05-22T05:55:37.000Z","updated_at":"2025-05-07T03:40:19.000Z","dependencies_parsed_at":"2025-05-07T04:25:08.628Z","dependency_job_id":"1aa4c1fb-faea-4e1b-8573-8ea1955af34a","html_url":"https://github.com/stackus/errors","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/stackus/errors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackus%2Ferrors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackus%2Ferrors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackus%2Ferrors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackus%2Ferrors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stackus","download_url":"https://codeload.github.com/stackus/errors/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stackus%2Ferrors/sbom","scorecard":{"id":845476,"data":{"date":"2025-08-11","repo":{"name":"github.com/stackus/errors","commit":"a8785ad20a2df2c105752ab590b6f06345c25b8d"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 0/27 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/stackus/errors/ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/ci.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/stackus/errors/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/stackus/errors/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:35: update your workflow using https://app.stepsecurity.io/secureworkflow/stackus/errors/ci.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 1 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T21:20:04.731Z","repository_id":50785497,"created_at":"2025-08-23T21:20:04.731Z","updated_at":"2025-08-23T21:20:04.731Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28808327,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T07:14:39.408Z","status":"ssl_error","status_checked_at":"2026-01-27T07:14:39.098Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["error-handling","errors","golang","grpc","http"],"created_at":"2026-01-27T07:38:06.185Z","updated_at":"2026-01-27T07:38:10.170Z","avatar_url":"https://github.com/stackus.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"![](https://github.com/stackus/errors/workflows/CI/badge.svg)\n[![Go Report Card](https://goreportcard.com/badge/github.com/stackus/errors)](https://goreportcard.com/report/github.com/stackus/errors)\n[![](https://godoc.org/github.com/stackus/errors?status.svg)](https://pkg.go.dev/github.com/stackus/errors)\n\n# errors\n\nBuilds on Go 1.13 errors by adding HTTP statuses and GRPC codes to them.\n\n## Installation\n\n    go get -u github.com/stackus/errors\n\n## Prerequisites\n\nGo 1.20 or later is required to use this package.\n\n## Embeddable codes\n\nThis library allows the use and helps facilitate the embedding of a type code, HTTP status, and GRPC code into errors\nthat can then be shared between services.\n\n### Type Codes\n\nType codes are strings that are returned by any error that implements `errors.TypeCoder`.\n\n    type TypeCoder interface {\n        error\n        TypeCode() string\n    }\n\n### HTTP Statuses\n\nHTTP statuses are integer values that have defined in the `net/http` package and are returned by any error that\nimplements `errors.HTTPCoder`.\n\n    type HTTPCoder interface {\n        error\n        HTTPCode() int\n    }\n\n### GRPC Codes\n\nGRPC codes are `codes.Code` are int64 values defined in the `google.golang.org/grpc/codes` package and are returned by\nany error that implements `errors.GRPCCoder`.\n\n    type GRPCCoder interface {\n        error\n        GRPCCode() codes.Code\n    }\n\n### Packaged Error Types\n\nThe package also comes with many defined errors that are named in a way to reflect the GRPC code or HTTP status they\nrepresent. The list of embeddable `errors.Error` types can be\nfound [here](https://github.com/stackus/errors/blob/master/types.go).\n\n## Wrapping errors\n\nThe `errors.Wrap(error, string) error` function is used to wrap errors combining messages in most cases. However, when\nthe function is used with an error that has implemented `errors.TypeCoder` the message is not altered, and the error is\nembedded instead.\n\n```go\n// Wrapping normal errors appends the error message\nerr := errors.Wrap(fmt.Errorf(\"sql error\"), \"error message\")\nfmt.Println(err) // Outputs: \"error message: sql error\"\n\n// Wrapping errors.TypeCoder errors embeds the type\nerr := errors.Wrap(errors.ErrNotFound, \"error message\")\nfmt.Println(err) // Outputs: \"error message\"\n\n```\n\nWrapping multiple times will add additional prefixes to the error message.\n\n```go\n// Wrapping multiple times\nerr := errors.Wrap(errors.ErrNotFound, \"error message\")\nerr = errors.Wrap(err, \"prefix\")\nerr = errors.Wrap(err, \"another\")\nfmt.Println(err) // Outputs: \"another: prefix: error message\"\n```\n\n### Wrapping using the errors.Err* errors\n\nIt is possible to use the package errors to wrap existing errors to add or override Type, HTTP code, or GRPC status codes.\n\n```go\n// Err will use the wrapped error .Error() output as the message\nerr := errors.ErrBadRequest.Err(fmt.Errorf(\"some error\"))\n// Msg and Msgf returns the Error with just the custom message applied\nerr = errors.ErrBadRequest.Msgf(\"%d total reasons\", 7)\n// Wrap and Wrapf will accept messages and simple wrap the error\nerr = errors.ErrUnauthorized.Wrap(err, \"some message\")\n```\n\nBoth errors can be checked for using the `Is()` and `As()` methods when you wrap errors with the package errors this way.\n\n## Getting type, HTTP status, or GRPC code\n\nThe Go 1.13 `errors.As(error, interface{}) bool` function from the standard `errors` package can be used to turn an\nerror into any of the three \"Coder\" interfaces documented above.\n\n    err := errors.Wrap(errors.NotFound, \"error message\")\n    var coder errors.TypeCoder\n    if errors.As(err, \u0026coder) {\n        fmt.Println(coder.TypeCode()) // Outputs: \"NOT_FOUND\"\n    }\n\n\u003e The functions `Is()`, `As()`, and `Unwrap()` from the standard `errors` package have all been made available in this package as proxies for convenience.\n\nThe functions `errors.TypeCode(error) string`, `errors.HTTPCode(error) int`, and `errors.GRPCCode(error) codes.Code` can\nbe used to fetch specific code. They're more convenient to use than the interfaces directly. The catch is they have\ndefined rules for the values they return.\n\nThe function `errors.Join(errs ...error) error`, made available in Go 1.20 has been added to this package as an additional convenience.\n\n#### errors.TypeCode(error) string\n\nIf the error implements or has wrapped an error that implements `errors.TypeCoder` it will return the code from that\nerror. If no error is found to support the interface then the string `\"UNKNOWN\"` is returned. Nil errors result in a\nblank string being returned.\n\n    fmt.Println(errors.TypeCode(errors.ErrNotFound)) // Outputs: \"NOT_FOUND\"\n    fmt.Println(errors.TypeCode(fmt.Errorf(\"an error\"))) // Outputs: \"UNKNOWN\"\n    fmt.Println(errors.TypeCode(nil)) // Outputs: \"\"\n\n#### errors.HTTPCode(error) int\n\nIf the error implements or has wrapped an error that implements `errors.HTTPCoder` it will return the status from that\nerror. If no error is found to support the interface then `http.StatusNotExtended` is returned. Nil errors result\nin `http.StatusOK` being returned.\n\n    fmt.Println(errors.HTTPCode(errors.ErrNotFound)) // Outputs: 404\n    fmt.Println(errors.HTTPCode(fmt.Errorf(\"an error\"))) // Outputs: 510\n    fmt.Println(errors.HTTPCode(nil)) // Outputs: 200\n\n#### errors.GRPCCode(error) codes.Code\n\nIf the error implements or has wrapped an error that implements `errors.GRPCCoder` it will return the code from that\nerror. If no error is found to support the interface then `codes.Unknown` is returned. Nil errors result in `codes.OK`\nbeing returned.\n\n    fmt.Println(errors.GRPCCode(errors.ErrNotFound)) // Outputs: 5\n    fmt.Println(errors.GRPCCode(fmt.Errorf(\"an error\"))) // Outputs: 2\n    fmt.Println(errors.GRPCCode(nil)) // Outputs: 0\n\n#### Why Unknown? Why not default to internal errors?\n\nPart of the reason you'd want to use a library that adds code to your errors is because you want to better identify the\nproblems in your application. By marking un-coded errors as \"Unknown\" errors they'll stand out from any errors you've\nmarked as `codes.Internal` for example.\n\n## Transmitting errors with GRPC\n\nThe functions `SendGRPCError(error) error` and `ReceiveGRPCError(error) error` provide a way to convert\na `status.Status` and its error into an error that provides codes and vice versa. You can use these in your server and\nclient handlers directly, or they can be used with GRPC interceptors.\n\nServer Interceptor Example:\n\n    // Unary only example\n    func serverErrorUnaryInterceptor() grpc.UnaryServerInterceptor {\n\t    return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {\n\t\t    return resp, errors.SendGRPCError(err)\n    \t}\n    }\n\n    server := grpc.NewServer(grpc.ChainUnaryInterceptor(serverErrorUnaryInterceptor()), ...others)\n\nClient Interceptor Example:\n\n    // Unary only example\n    func clientErrorUnaryInterceptor() grpc.UnaryClientInterceptor {\n\t    return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {\n\t\t    return errors.ReceiveGRPCError(invoker(ctx, method, req, reply, cc, opts...))\n    \t}\n    }\n\n    cc, err := grpc.Dial(uri, grpc.WithChainUnaryInterceptor(clientErrorUnaryInterceptor()), ...others)\n\n### Comparing received errors\n\nServers and clients may not always use a shared library when exchanging errors. In fact there isn't any requirement that\nthe server and client both use this library to exchange errors.\n\nWhen comparing received errors with `errors.Is(error, error) bool` the checks are a little more loose. A received error\nis considered to be the same if **ANY** of the codes are a match. This differs from a strict equality check for the\nserver before the error was sent.\n\nThe \"Code\" functions and the \"Coder\" interfaces continue to work the same on a client as they did on the server that\nsent the error.\n\n## Contributing\n\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n\nPlease make sure to update tests as appropriate.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackus%2Ferrors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstackus%2Ferrors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstackus%2Ferrors/lists"}