diff options
Diffstat (limited to 'src/pkg/exp/exception/exception.go')
-rw-r--r-- | src/pkg/exp/exception/exception.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/pkg/exp/exception/exception.go b/src/pkg/exp/exception/exception.go new file mode 100644 index 000000000..45e0be3f1 --- /dev/null +++ b/src/pkg/exp/exception/exception.go @@ -0,0 +1,83 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This package illustrates how basic try-catch exception handling +// can be emulated using goroutines, channels, and closures. +// +// This package is *not* intended as a general exception handler +// library. +// +package exception + +import ( + "fmt"; + "runtime"; +) + +// A Handler function handles an arbitrary exception value x. +type Handler func(x interface{}) + +// An Exception carries an exception value. +type Exception struct { + Value interface{}; // Value may be the nil exception +} + +// Try invokes a function f with a Handler to throw exceptions. +// The function f may terminate abnormally with an arbitrary +// exception x by calling throw(x) within f. If an exception is +// thrown, Try returns an *Exception; otherwise it returns nil. +// +// Usage pattern: +// +// if x := exception.Try(func(throw exception.Handler) { +// ... +// throw(42); // terminate f by throwing exception 42 +// ... +// }); x != nil { +// // catch exception, e.g. print it +// fmt.Println(x.Value); +// } +// +// Alternative: +// +// exception.Try(func(throw exception.Handler) { +// ... +// throw(42); // terminate f by throwing exception 42 +// ... +// }).Catch(func (x interface{}) { +// // catch exception, e.g. print it +// fmt.Println(x); +// }) +// +func Try(f func(throw Handler)) *Exception { + h := make(chan *Exception); + + // execute try block + go func() { + f(func(x interface{}) { + h <- &Exception{x}; + runtime.Goexit(); + }); + h <- nil; // clean termination + }(); + + return <-h; +} + + +// If x != nil, Catch invokes f with the exception value x.Value. +// See Try for usage patterns. +func (x *Exception) Catch(f Handler) { + if x != nil { + f(x.Value) + } +} + + +func (x *Exception) String() string { + if x != nil { + return fmt.Sprintf("exception: %v", x.Value) + } + return ""; +} |