@@ -29,7 +29,7 @@ <h2 id="introduction">Introduction</h2>
29
29
should read first.
30
30
</ p >
31
31
32
- < h3 id ="read "> Examples</ h3 >
32
+ < h3 id ="examples "> Examples</ h3 >
33
33
34
34
< p >
35
35
The < a href ="/src/pkg/ "> Go package sources</ a >
@@ -2569,10 +2569,175 @@ <h2 id="errors">Errors</h2>
2569
2569
}
2570
2570
</ pre >
2571
2571
2572
- < h3 id ="panic_recover "> Panic and recover </ h3 >
2572
+ < h3 id ="panic "> Panic</ h3 >
2573
2573
2574
2574
< p >
2575
- TODO: Short discussion of panic and recover goes here.
2575
+ The usual way to report an error to a caller is to return an
2576
+ < code > os.Error</ code > as an extra return value. The canonical
2577
+ < code > Read</ code > method is a well-known instance; it returns a byte
2578
+ count and an < code > os.Error</ code > . But what if the error is
2579
+ unrecoverable? Sometimes the program simply cannot continue.
2580
+ </ p >
2581
+
2582
+ < p >
2583
+ For this purpose, there is a built-in function < code > panic</ code >
2584
+ that in effect creates a run-time error that will stop the program
2585
+ (but see the next section). The function takes a single argument
2586
+ of arbitrary type—often a string—to be printed as the
2587
+ program dies. It's also a way to indicate that something impossible has
2588
+ happened, such as exiting an infinite loop. In fact, the compiler
2589
+ recognizes a < code > panic</ code > at the end of a function and
2590
+ suppresses the usual check for a < code > return</ code > statement.
2591
+ </ p >
2592
+
2593
+
2594
+ < pre >
2595
+ // A toy implementation of cube root using Newton's method.
2596
+ func CubeRoot(x float64) float64 {
2597
+ z := x/3 // Arbitrary intitial value
2598
+ for i := 0; i < 1e6 ; i++ {
2599
+ prevz : = z
2600
+ z - = (z*z*z-x) / (3*z*z)
2601
+ if veryClose(z, prevz) {
2602
+ return z
2603
+ }
2604
+ }
2605
+ // A million iterations has not converged; something is wrong.
2606
+ panic(fmt.Sprintf("CubeRoot(%g) did not converge", x)
2607
+ }
2608
+ </ pre>
2609
+
2610
+ < p >
2611
+ This is only an example but real library functions should
2612
+ avoid < code > panic</ code > . If the problem can be masked or worked
2613
+ around, it's always better to let things continue to run rather
2614
+ than taking down the whole program. One possible counterexample
2615
+ is during initialization: if the library truly cannot set itself up,
2616
+ it might be reasonable to panic, so to speak.
2617
+ </ p >
2618
+
2619
+ < pre >
2620
+ var user = os.Getenv("USER")
2621
+
2622
+ func init() {
2623
+ if user == "" {
2624
+ panic("no value for $USER")
2625
+ }
2626
+ }
2627
+ </ pre >
2628
+
2629
+ < h3 id ="recover "> Recover</ h3 >
2630
+
2631
+ < p >
2632
+ When < code > panic</ code > is called, including implicitly for run-time
2633
+ errors such indexing an array out of bounds or failing a type
2634
+ assertion, it immediately stops execution of the current function
2635
+ and begins unwinding the stack of the goroutine, running any deferred
2636
+ functions along the way. If that unwinding reaches the top of the
2637
+ goroutine's stack, the program dies. However, it is possible to
2638
+ use the built-in function < code > recover</ code > to regain control
2639
+ of the goroutine and resume normal execution.
2640
+ </ p >
2641
+
2642
+ < p >
2643
+ A call to < code > recover</ code > stops the unwinding and returns the
2644
+ argument passed to < code > panic</ code > . Because the only code that
2645
+ runs while unwinding is inside deferred functions, < code > recover</ code >
2646
+ is only useful inside deferred functions.
2647
+ </ p >
2648
+
2649
+ < p >
2650
+ One application of < code > recover</ code > is to shut down a failing goroutine
2651
+ inside a server without killing the other executing goroutines.
2652
+ </ p >
2653
+
2654
+ < pre >
2655
+ func server(workChan < -chan *Work) {
2656
+ for work : = range workChan {
2657
+ safelyDo(work)
2658
+ }
2659
+ }
2660
+
2661
+ func safelyDo(work *Work) {
2662
+ defer func() {
2663
+ if err : = recover(); err ! = nil {
2664
+ log.Stderr( "work failed:", err)
2665
+ }
2666
+ }()
2667
+ do(work)
2668
+ }
2669
+ </ pre>
2670
+
2671
+ < p >
2672
+ In this example, if < code > do(work)</ code > panics, the result will be
2673
+ logged and the goroutine will exit cleanly without disturbing the
2674
+ others. There's no need to do anything else in the deferred closure;
2675
+ calling < code > recover</ code > handles the condition completely.
2676
+ </ p >
2677
+
2678
+ < p >
2679
+ Note that with this recovery pattern in place, the < code > do</ code >
2680
+ function (and anything it calls) can get out of any bad situation
2681
+ cleanly by calling < code > panic</ code > . We can use that idea to
2682
+ simplify error handling in complex software. Let's look at an
2683
+ idealized excerpt from the < code > regexp</ code > package, which reports
2684
+ parsing errors by calling < code > panic</ code > with a local
2685
+ < code > Error</ code > type. Here's the definition of < code > Error</ code > ,
2686
+ an < code > error</ code > method, and the < code > Compile</ code > function.
2687
+ </ p >
2688
+
2689
+ < pre >
2690
+ // Error is the type of a parse error; it satisfies os.Error.
2691
+ type Error string
2692
+ func (e Error) String() string {
2693
+ return string(e)
2694
+ }
2695
+
2696
+ // error is a method of *Regexp that reports parsing errors by
2697
+ // panicking with an Error.
2698
+ func (regexp *Regexp) error(err string) {
2699
+ panic(Error(err))
2700
+ }
2701
+
2702
+ // Compile returns a parsed representation of the regular expression.
2703
+ func Compile(str string) (regexp *Regexp, err os.Error) {
2704
+ regexp = new(Regexp)
2705
+ // doParse will panic if there is a parse error.
2706
+ defer func() {
2707
+ if e := recover(); e != nil {
2708
+ regexp = nil // Clear return value.
2709
+ err = e.(Error) // Will re-panic if not a parse error.
2710
+ }
2711
+ }()
2712
+ return regexp.doParse(str), nil
2713
+ }
2714
+ </ pre >
2715
+
2716
+ < p >
2717
+ If < code > doParse</ code > panics, the recovery block will set the
2718
+ return value to < code > nil</ code > —deferred functions can modify
2719
+ named return values. It then will then check, in the assignment
2720
+ to < code > err</ code > , that the problem was a parse error by asserting
2721
+ that it has type < code > Error</ code > .
2722
+ If it does not, the type assertion will fail, causing a run-time error
2723
+ that continues the stack unwinding as though nothing had interrupted
2724
+ it. This check means that if something unexpected happens, such
2725
+ as an array index out of bounds, the code will fail even though we
2726
+ are using < code > panic</ code > and < code > recover</ code > to handle
2727
+ user-triggered errors.
2728
+ </ p >
2729
+
2730
+ < p >
2731
+ With this error handling in place, the < code > error</ code > method
2732
+ makes it easy to report parse errors without worrying about unwinding
2733
+ the parse stack by hand.
2734
+ </ p >
2735
+
2736
+ < p >
2737
+ Useful though this pattern is, it should be used only within a package.
2738
+ < code > Parse</ code > turns its internal < code > panic</ code > calls into
2739
+ < code > os.Error</ code > values; it does not expose < code > panics</ code >
2740
+ to its client. That is a good rule to follow.
2576
2741
</ p >
2577
2742
2578
2743
0 commit comments