• 不要 Panic

    不要 Panic

    生产级的代码必须避免 panics 。panics 是级联故障的主要源头。如果错误发生,函数应该返回错误并且允许调用者决定如果处理它。

    BadGood
    1. func foo(bar string) {
    2. if len(bar) == 0 {
    3. panic("bar must not be empty")
    4. }
    5. // …
    6. }
    7. func main() {
    8. if len(os.Args) != 2 {
    9. fmt.Println("USAGE: foo <bar>")
    10. os.Exit(1)
    11. }
    12. foo(os.Args[1])
    13. }
    1. func foo(bar string) error {
    2. if len(bar) == 0
    3. return errors.New("bar must not be empty")
    4. }
    5. // …
    6. return nil
    7. }
    8. func main() {
    9. if len(os.Args) != 2 {
    10. fmt.Println("USAGE: foo <bar>")
    11. os.Exit(1)
    12. }
    13. if err := foo(os.Args[1]); err != nil {
    14. panic(err)
    15. }
    16. }

    Panic/recover 并不是错误处理策略。程序只有在遇到无法处理的情况下才可以 panic ,例如,nil 引用。程序初始化时是一个例外情况:程序启动时遇到需要终止执行的错误可能会 painc 。

    1. var _statusTemplate = template.Must(template.New("name").Parse("_statusHTML"))

    即使是在测试中,也应优先选择 t.Fatalt.FailNow 而非 panic,以确保测试标记为失败。

    BadGood
    1. // func TestFoo(t testing.T)
    2. f, err := ioutil.TempFile("", "test")
    3. if err != nil {
    4. panic("failed to set up test")
    5. }
    1. // func TestFoo(t testing.T)
    2. f, err := ioutil.TempFile("", "test")
    3. if err != nil {
    4. t.Fatal("failed to set up test")
    5. }