unknwon/the-way-to-go_ZH_CN · error

"ERROR occurred:" + err.Error()

Error message

"ERROR occurred:" + err.Error()

What it means

The canonical error-to-panic idiom shown in section 13.2: if err != nil { panic("ERROR occurred:" + err.Error()) }. It is presented as the last-resort branch when a recoverable path does not exist; the same section explicitly warns not to use panic casually ('不能随意地用 panic() 中止程序') and to try to remedy errors first.

Source

Thrown at eBook/13.2.md:55

一个检查程序是否被已知用户启动的具体例子:

```go
var user = os.Getenv("USER")

func check() {
	if user == "" {
		panic("Unknown user: no value for $USER")
	}
}
```

可以在导入包的 `init()` 函数中检查这些。

当发生错误必须中止程序时,`panic()` 可以用于错误处理模式:

```go
if err != nil {
	panic("ERROR occurred:" + err.Error())
}
```

<u>Go panicking</u>:

在多层嵌套的函数调用中调用 `panic()`,可以马上中止当前函数的执行,所有的 `defer` 语句都会保证执行并把控制权交还给接收到 panic 的函数调用者。这样向上冒泡直到最顶层,并执行(每层的) `defer`,在栈顶处程序崩溃,并在命令行中用传给 `panic()` 的值报告错误情况:这个终止过程就是 *panicking*。

标准库中有许多包含 `Must` 前缀的函数,像 `regexp.MustComplie()` 和 `template.Must()`;当正则表达式或模板中转入的转换字符串导致错误时,这些函数会 `panic()`。

不能随意地用 `panic()` 中止程序,必须尽力补救错误让程序能继续执行。

## 链接

- [目录](directory.md)
- 上一节:[错误处理](13.1.md)
- 下一节:[从 panic 中恢复 (recover)](13.3.md)

View on GitHub (pinned to 7a54d34d36)

Solutions

  1. Return the error to the caller instead: add error to the signature and wrap with fmt.Errorf for context
  2. If it is genuinely fatal startup code, use log.Fatalf("ERROR occurred: %v", err) for a clean, timestamped exit
  3. Use %v/%w formatting instead of string concatenation so the cause stays inspectable
  4. When a dependency panics like this, wrap the call site with a deferred recover and convert the panic value to an error

Example fix

// before
if err != nil {
    panic("ERROR occurred:" + err.Error())
}

// after
if err != nil {
    return fmt.Errorf("ERROR occurred: %w", err)
}
// or, at top level only:
if err != nil { log.Fatalf("ERROR occurred: %v", err) }
Defensive patterns

Strategy: try-catch

Try / catch

// boundary guard around code that uses the panic idiom
defer func() {
    if r := recover(); r != nil {
        err = fmt.Errorf("recovered: %v", r)
    }
}()
result = riskyCall()

Prevention

When it happens

Trigger: Any error value reaching this branch — typically a failed file open, missing configuration, or failed connection during program setup where the author chose termination over propagating the error up the stack.

Common situations: Startup-phase code in main/init (config load, DB connect) where error plumbing was shortcut; third-party libraries that panic instead of returning error values, forcing callers to defend with recover.

Related errors


AI-assisted analysis of unknwon/the-way-to-go_ZH_CN@7a54d34d36 (2026-08-15). Data as JSON: /api/errors/0790c1e8431dfef0. Report an issue: GitHub.