{"id":16908809,"url":"https://github.com/hanjm/errors","last_synced_at":"2026-02-26T23:33:32.907Z","repository":{"id":57495511,"uuid":"102189930","full_name":"hanjm/errors","owner":"hanjm","description":"errors with paired message and caller stack frame","archived":false,"fork":false,"pushed_at":"2019-09-08T03:21:58.000Z","size":18,"stargazers_count":20,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-11T15:59:19.816Z","etag":null,"topics":["error-handling","errors","golang","production","stacktrace"],"latest_commit_sha":null,"homepage":null,"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/hanjm.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}},"created_at":"2017-09-02T10:45:35.000Z","updated_at":"2023-09-19T02:52:07.000Z","dependencies_parsed_at":"2022-09-02T20:22:41.707Z","dependency_job_id":null,"html_url":"https://github.com/hanjm/errors","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hanjm/errors","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanjm%2Ferrors","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanjm%2Ferrors/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanjm%2Ferrors/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanjm%2Ferrors/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hanjm","download_url":"https://codeload.github.com/hanjm/errors/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hanjm%2Ferrors/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29877012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T22:37:10.609Z","status":"ssl_error","status_checked_at":"2026-02-26T22:37:09.019Z","response_time":89,"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","production","stacktrace"],"created_at":"2024-10-13T18:53:04.930Z","updated_at":"2026-02-26T23:33:32.887Z","avatar_url":"https://github.com/hanjm.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![GoDoc](https://godoc.org/github.com/hanjm/errors?status.svg)](https://godoc.org/github.com/hanjm/errors)\n[![Go Report Card](https://goreportcard.com/badge/github.com/hanjm/errors)](https://goreportcard.com/report/github.com/hanjm/errors)\n[![code-coverage](http://gocover.io/_badge/github.com/hanjm/errors)](http://gocover.io/github.com/hanjm/errors)\n\nerrors包装error对象, 添加调用栈及附加自定义信息, 以便于从日志中快速定位问题.\n特点:\n1. 相比 github.com/pkg/errors github.com/juju/errors 开销小, 只在最早出错的地方会调用runtime.Callers, 只调用一次.\n2. 对齐调用栈和附加上下文信息, 按[ 文件名:行号 函数名:message ]分行格式化输出, funcName不显示package path, fileName不显示src之前的字符. Goland等IDE可以在控制台上点击错误信息定位源码.\n3. 精简调用栈输出, 默认忽略标准库和 github.com 下的包的调用栈, 也可以用SetFilterFunc自定义一些filter, 忽略一些固定的框架的调用栈信息.\n\n文章:\n[Go如何优雅地错误处理(Error Handling and Go 1)](https://imhanjm.com/2018/07/08/go%E5%A6%82%E4%BD%95%E4%BC%98%E9%9B%85%E5%9C%B0%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86(error%20handling%20and%20go%201)/)\n\ndoc:\n```go\nfunc Errorf(err error, format string, a ...interface{}) error {\n //...\n}\n用于包装上一步New/Errorf返回的error/*Err, 添加错误注释, 如 比\"xx function error\"更直接的错误说明、调用函数的参数值等\n \t\t\t如果参数error类型不为*Err(error常量或自定义error类型或nil), 用于最早出错的地方, 会收集调用栈\n \t\t\t如果参数error类型为*Err, 不会收集调用栈.\n上层调用方可以通过GetInnerMost得到最里层被包装过的error常量\n\n```go\n// 示例代码1 非error常量的情况\n// ExampleFunc1 调用func2 func2调用func3\n// 在func3使用errors.Errorf时第一个参数传nil收集最完整的调用栈,\n// 其他地方用errors.Errorf时第一个参数传上一步返回的error, 最后打log\nfunc func1() {\n\trequestID := \"1\"\n\terr := func2()\n\tif err != nil {\n\t\terr = Errorf(err, \"[%s] 123\", requestID)\n\t\tlog.Print(err)\n\t\t// log ouuput:\n\t\t/*\n\t\t\t2017/09/02 18:55:35 [errors/example.go:33:func3:unexpected param]\n\t\t\t[ errors/example.go:25 func2:i=3]\n\t\t\t[ errors/example.go:15 func1:[1] 123]\n\t\t\t[ errors/error_test.go:22 TestExample:]\n\t\t*/\n\t}\n\treturn\n}\n\nfunc func2() (err error) {\n\ti := 3\n\terr = func3(i)\n\tif err != nil {\n\t\treturn Errorf(err, \"i=%d\", i)\n\t}\n\treturn\n}\n\nfunc func3(i int) (err error) {\n\treturn Errorf(nil, \"unexpected param\")\n}\n\nvar (\n\terrSomeUnexpected = errors.New(\"someUnexpected\")\n)\n\n// 示例代码2  error常量的情况\n// ExampleFunc11 调用func22 func22调用func33\n// 在func33使用errors.Errorf包装error常量,收集最完整的调用栈, 最后打log\n// 调用func22处可以调GetInnerMost()方法来取到最里层被包装的error常量\nfunc func11() {\n\trequestID := \"11\"\n\terr := func22()\n\tif err != nil {\n\t\terr = Errorf(err, \"[%s] 123\", requestID)\n\t\tlog.Print(err)\n\t\t// log output:\n\t\t/*\n\t\t2017/09/02 18:55:35 [errors/example.go:67:func33:unexpected param err:someUnexpected]\n\t\t[ errors/example.go:56 func22:i=3]\n\t\t[ errors/example.go:46 func11:[11] 123]\n\t\t[ errors/error_test.go:26 TestExample2:]\n\t\t*/\n\t}\n\treturn\n}\n\nfunc func22() (err error) {\n\ti := 3\n\terr = func33(i)\n\tif err != nil {\n\t\tif err2, ok := err.(*Err); ok \u0026\u0026 err2.Inner() == errSomeUnexpected {\n\t\t\tfmt.Printf(\"==\\n识别到上一步的std error:%s\\n==\\n\", err2.Inner())\n\t\t}\n\t\treturn Errorf(err, \"i=%d\", i)\n\t}\n\treturn\n}\n\nfunc func33(i int) (err error) {\n\treturn Errorf(errSomeUnexpected, \"unexpected param\")\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhanjm%2Ferrors","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhanjm%2Ferrors","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhanjm%2Ferrors/lists"}