exec: introduce ExitError

The existing code uses *os.Waitmsg as an os.Error,
but *os.Waitmsg is really just a stringer.

Introduce an explicit error type for the real error.

Not to be submitted until just before error goes in;
the gofix for error updates type assertions
        err.(*os.Waitmsg)
to
        err.(*exec.ExitError)

The seemingly redundant String method will become
an Error method when error goes in, and will no longer
be redundant.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5331044
This commit is contained in:
Russ Cox 2011-11-01 21:49:44 -04:00
parent c93b6a1756
commit 451a1fa46d
2 changed files with 16 additions and 7 deletions

View file

@ -203,7 +203,7 @@ func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err os.Error) {
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *os.Waitmsg. Other error types may be
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (c *Cmd) Run() os.Error {
if err := c.Start(); err != nil {
@ -256,6 +256,15 @@ func (c *Cmd) Start() os.Error {
return nil
}
// An ExitError reports an unsuccessful exit by a command.
type ExitError struct {
*os.Waitmsg
}
func (e *ExitError) String() string {
return e.Waitmsg.String()
}
// Wait waits for the command to exit.
// It must have been started by Start.
//
@ -264,7 +273,7 @@ func (c *Cmd) Start() os.Error {
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *os.Waitmsg. Other error types may be
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (c *Cmd) Wait() os.Error {
if c.Process == nil {
@ -290,7 +299,7 @@ func (c *Cmd) Wait() os.Error {
if err != nil {
return err
} else if !msg.Exited() || msg.ExitStatus() != 0 {
return msg
return &ExitError{msg}
}
return copyError

View file

@ -53,8 +53,8 @@ func TestCatStdin(t *testing.T) {
func TestCatGoodAndBadFile(t *testing.T) {
// Testing combined output and error values.
bs, err := helperCommand("cat", "/bogus/file.foo", "exec_test.go").CombinedOutput()
if _, ok := err.(*os.Waitmsg); !ok {
t.Errorf("expected Waitmsg from cat combined; got %T: %v", err, err)
if _, ok := err.(*ExitError); !ok {
t.Errorf("expected *ExitError from cat combined; got %T: %v", err, err)
}
s := string(bs)
sp := strings.SplitN(s, "\n", 2)
@ -81,12 +81,12 @@ func TestNoExistBinary(t *testing.T) {
func TestExitStatus(t *testing.T) {
// Test that exit values are returned correctly
err := helperCommand("exit", "42").Run()
if werr, ok := err.(*os.Waitmsg); ok {
if werr, ok := err.(*ExitError); ok {
if s, e := werr.String(), "exit status 42"; s != e {
t.Errorf("from exit 42 got exit %q, want %q", s, e)
}
} else {
t.Fatalf("expected Waitmsg from exit 42; got %T: %v", err, err)
t.Fatalf("expected *ExitError from exit 42; got %T: %v", err, err)
}
}