unknwon/the-way-to-go_ZH_CN · info
things aren’t good
Error message
things aren’t good
What it means
Textbook anti-pattern, shown deliberately so the book can say 'don't do this': a boolean good is set by testing an error condition, and then !good converts it back into a fresh errors.New("things aren’t good"). The illustrated problem: re-encoding an error you already have into a vaguer one discards the original cause; the correct move, shown right below, is to test the error value directly (if err1 != nil { ... }).
Source
Thrown at eBook/16.10.md:16
# 16.10 糟糕的错误处理
译者注:该小结关于错误处理的观点,译者并不完全赞同,关于本小结的部分想法请参考 [关于 16.10.2 小节错误处理的一些见解](Discussion_about_16.10.md)。
依附于[第 13 章](13.0.md)模式的描述和[第 17.1 小节](17.1.md)与[第 17.2.4 小节](17.2.md)的总结。
## 16.10.1 不要使用布尔值:
像下面代码一样,创建一个布尔型变量用于测试错误条件是多余的:
```go
var good bool
// 测试一个错误,`good` 被赋为 `true` 或者 `false`
if !good {
return errors.New("things aren’t good")
}
```
立即检测一个错误:
```go
... err1 := api.Func1()
if err1 != nil { … }
```
## 16.10.2 避免错误检测使代码变得混乱:
避免写出这样的代码:
```go
... err1 := api.Func1()
if err1 != nil {
fmt.Println("err: " + err.Error())View on GitHub (pinned to 7a54d34d36)
Solutions
- Delete the boolean entirely and propagate the original error: if err := api.Func1(); err != nil { return err }
- If a boolean API must stay, carry the error alongside it (ok bool, err error) and never synthesize a new message
- When adding context, wrap rather than replace: return fmt.Errorf("calling Func1: %w", err)
- Add lint guardrails: errcheck and staticcheck flag the ignored errors that push code toward this pattern
Example fix
// before
var good bool
// an error is tested; good becomes true or false
if !good {
return errors.New("things aren’t good") // original cause lost
}
// after (the book's recommendation: check the error immediately)
if err1 := api.Func1(); err1 != nil {
return fmt.Errorf("func1 failed: %w", err1)
} Defensive patterns
Strategy: try-catch
Try / catch
// capture the error where it is produced; do not re-encode it into a bool
if err := api.Func1(); err != nil {
return fmt.Errorf("func1: %w", err)
} Prevention
- Never collapse an error into a success bool at an API boundary; pass (bool, error) pairs if a flag is truly needed
- Wrap with %w rather than minting new errors.New messages that drop the cause
- Enable errcheck/staticcheck in CI to catch ignored errors that push code toward bool workarounds
- When reviewing legacy ok-flag APIs, add error returns before adding new callers
When it happens
Trigger: Only appears if you copy this shape into your code: an api.Func1()-style call whose error is squeezed into good bool, and !good then produces this stringly error. At runtime it fires whenever the underlying operation failed — with all diagnostic detail stripped.
Common situations: Wrapper layers that reduce errors to booleans (ok flags from internal helpers); legacy success-flag APIs; test helpers that report only pass/fail and then stringify; debug sessions where the root cause is unrecoverable because this message replaced it.
Related errors
- I won't be able to do a sqrt of negative number!
- expected GET
- "ERROR occurred:" + err.Error()
- "ERROR occurred: " + err.Error()
- stack is empty
AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15).
Data as JSON: /api/errors/3b3c461763a8ee0b.
Report an issue: GitHub.