Enhanced error messages.

This commit is contained in:
Zach Klippenstein 2015-04-29 12:23:51 -05:00
parent d0b99d9f57
commit a6b8a6fa03
11 changed files with 59 additions and 68 deletions

View file

@ -8,10 +8,9 @@ import (
"log" "log"
adb "github.com/zach-klippenstein/goadb" adb "github.com/zach-klippenstein/goadb"
"github.com/zach-klippenstein/goadb/wire"
) )
var port = flag.Int("p", wire.AdbPort, "") var port = flag.Int("p", goadb.AdbPort, "")
func main() { func main() {
flag.Parse() flag.Parse()

View file

@ -72,7 +72,7 @@ func (c *DeviceClient) RunCommand(cmd string, args ...string) (string, error) {
if err = conn.SendMessage([]byte(req)); err != nil { if err = conn.SendMessage([]byte(req)); err != nil {
return "", err return "", err
} }
if err = wire.ReadStatusFailureAsError(conn, []byte(req)); err != nil { if err = wire.ReadStatusFailureAsError(conn, req); err != nil {
return "", err return "", err
} }
@ -147,16 +147,16 @@ func (c *DeviceClient) getAttribute(attr string) (string, error) {
func (c *DeviceClient) dialDevice() (*wire.Conn, error) { func (c *DeviceClient) dialDevice() (*wire.Conn, error) {
conn, err := c.dialer.Dial() conn, err := c.dialer.Dial()
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("error dialing adb server: %+v", err)
} }
req := fmt.Sprintf("host:%s", c.descriptor.getTransportDescriptor()) req := fmt.Sprintf("host:%s", c.descriptor.getTransportDescriptor())
if err = wire.SendMessageString(conn, req); err != nil { if err = wire.SendMessageString(conn, req); err != nil {
conn.Close() conn.Close()
return nil, err return nil, fmt.Errorf("error connecting to device '%s': %+v", c.descriptor, err)
} }
if err = wire.ReadStatusFailureAsError(conn, []byte(req)); err != nil { if err = wire.ReadStatusFailureAsError(conn, req); err != nil {
conn.Close() conn.Close()
return nil, err return nil, err
} }
@ -167,14 +167,14 @@ func (c *DeviceClient) dialDevice() (*wire.Conn, error) {
func (c *DeviceClient) getSyncConn() (*wire.SyncConn, error) { func (c *DeviceClient) getSyncConn() (*wire.SyncConn, error) {
conn, err := c.dialDevice() conn, err := c.dialDevice()
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("error connecting to device for sync: %+v", err)
} }
// Switch the connection to sync mode. // Switch the connection to sync mode.
if err := wire.SendMessageString(conn, "sync:"); err != nil { if err := wire.SendMessageString(conn, "sync:"); err != nil {
return nil, err return nil, fmt.Errorf("error requesting sync mode: %+v", err)
} }
if err := wire.ReadStatusFailureAsError(conn, []byte("sync")); err != nil { if err := wire.ReadStatusFailureAsError(conn, "sync"); err != nil {
return nil, err return nil, err
} }

View file

@ -20,9 +20,6 @@ type DirEntry struct {
type DirEntries struct { type DirEntries struct {
scanner wire.SyncScanner scanner wire.SyncScanner
// Called when finished iterating (successfully or not).
doneHandler func()
currentEntry *DirEntry currentEntry *DirEntry
err error err error
} }
@ -35,13 +32,13 @@ func (entries *DirEntries) Next() bool {
entry, done, err := readNextDirListEntry(entries.scanner) entry, done, err := readNextDirListEntry(entries.scanner)
if err != nil { if err != nil {
entries.err = err entries.err = err
entries.onDone() entries.Close()
return false return false
} }
entries.currentEntry = entry entries.currentEntry = entry
if done { if done {
entries.onDone() entries.Close()
return false return false
} }
@ -56,10 +53,10 @@ func (entries *DirEntries) Err() error {
return entries.err return entries.err
} }
func (entries *DirEntries) onDone() { // Close closes the connection to the adb.
if entries.doneHandler != nil { // Next() will call Close() before returning false.
entries.doneHandler() func (entries *DirEntries) Close() error {
} return entries.scanner.Close()
} }
func readNextDirListEntry(s wire.SyncScanner) (entry *DirEntry, done bool, err error) { func readNextDirListEntry(s wire.SyncScanner) (entry *DirEntry, done bool, err error) {
@ -72,28 +69,28 @@ func readNextDirListEntry(s wire.SyncScanner) (entry *DirEntry, done bool, err e
done = true done = true
return return
} else if id != "DENT" { } else if id != "DENT" {
err = fmt.Errorf("expected dir entry ID 'DENT', but got '%s'", id) err = fmt.Errorf("error reading dir entries: expected dir entry ID 'DENT', but got '%s'", id)
return return
} }
mode, err := s.ReadFileMode() mode, err := s.ReadFileMode()
if err != nil { if err != nil {
err = fmt.Errorf("error reading file mode: %v", err) err = fmt.Errorf("error reading dir entries: error reading file mode: %v", err)
return return
} }
size, err := s.ReadInt32() size, err := s.ReadInt32()
if err != nil { if err != nil {
err = fmt.Errorf("error reading file size: %v", err) err = fmt.Errorf("error reading dir entries: error reading file size: %v", err)
return return
} }
mtime, err := s.ReadTime() mtime, err := s.ReadTime()
if err != nil { if err != nil {
err = fmt.Errorf("error reading file time: %v", err) err = fmt.Errorf("error reading dir entries: error reading file time: %v", err)
return return
} }
name, err := s.ReadString() name, err := s.ReadString()
if err != nil { if err != nil {
err = fmt.Errorf("error reading file name: %v", err) err = fmt.Errorf("error reading dir entries: error reading file name: %v", err)
return return
} }

View file

@ -8,6 +8,11 @@ import (
"github.com/zach-klippenstein/goadb/wire" "github.com/zach-klippenstein/goadb/wire"
) )
const (
// Default port the adb server listens on.
AdbPort = 5037
)
/* /*
HostClient communicates with host services on the adb server. HostClient communicates with host services on the adb server.

View file

@ -8,7 +8,7 @@ type nilSafeDialer struct {
func (d nilSafeDialer) Dial() (*wire.Conn, error) { func (d nilSafeDialer) Dial() (*wire.Conn, error) {
if d.Dialer == nil { if d.Dialer == nil {
d.Dialer = wire.NewDialer("", 0) d.Dialer = wire.NewDialer("", AdbPort)
} }
return d.Dialer.Dial() return d.Dialer.Dial()

View file

@ -35,10 +35,7 @@ func listDirEntries(conn *wire.SyncConn, path string) (entries *DirEntries, err
return return
} }
return &DirEntries{ return &DirEntries{scanner: conn}, nil
scanner: conn,
doneHandler: func() { conn.Close() },
}, nil
} }
func receiveFile(conn *wire.SyncConn, path string) (io.ReadCloser, error) { func receiveFile(conn *wire.SyncConn, path string) (io.ReadCloser, error) {

View file

@ -5,17 +5,17 @@ import (
) )
type AdbError struct { type AdbError struct {
Request []byte Request string
ServerMsg string ServerMsg string
} }
var _ error = &AdbError{} var _ error = &AdbError{}
func (e *AdbError) Error() string { func (e *AdbError) Error() string {
if e.Request == nil { if e.Request == "" {
return fmt.Sprintf("server error: %s", e.ServerMsg) return fmt.Sprintf("server error: %s", e.ServerMsg)
} else { } else {
return fmt.Sprintf("server error for request '%s': %s", e.Request, e.ServerMsg) return fmt.Sprintf("server error for %s request: %s", e.Request, e.ServerMsg)
} }
} }

View file

@ -49,7 +49,7 @@ func (conn *Conn) RoundTripSingleResponse(req []byte) (resp []byte, err error) {
return nil, err return nil, err
} }
if err = ReadStatusFailureAsError(conn, req); err != nil { if err = ReadStatusFailureAsError(conn, string(req)); err != nil {
return nil, err return nil, err
} }

View file

@ -6,11 +6,6 @@ import (
"runtime" "runtime"
) )
const (
// Default port the adb server listens on.
AdbPort = 5037
)
/* /*
Dialer knows how to create connections to an adb server. Dialer knows how to create connections to an adb server.
*/ */
@ -35,12 +30,7 @@ func (d *netDialer) Dial() (*Conn, error) {
host = "localhost" host = "localhost"
} }
port := d.Port netConn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host, d.Port))
if port == 0 {
port = AdbPort
}
netConn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", host, port))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -87,30 +87,6 @@ func (s *realScanner) NewSyncScanner() SyncScanner {
return NewSyncScanner(s.reader) return NewSyncScanner(s.reader)
} }
// Reads the status, and if failure, reads the message and returns it as an error.
// If the status is success, doesn't read the message.
// req is just used to populate the AdbError, and can be nil.
func ReadStatusFailureAsError(s Scanner, req []byte) error {
status, err := s.ReadStatus()
if err != nil {
return err
}
if !status.IsSuccess() {
msg, err := s.ReadMessage()
if err != nil {
return err
}
return &AdbError{
Request: req,
ServerMsg: string(msg),
}
}
return nil
}
func (s *realScanner) Close() error { func (s *realScanner) Close() error {
return s.reader.Close() return s.reader.Close()
} }

View file

@ -1,6 +1,33 @@
package wire package wire
import "io" import (
"fmt"
"io"
)
// Reads the status, and if failure, reads the message and returns it as an error.
// If the status is success, doesn't read the message.
// req is just used to populate the AdbError, and can be nil.
func ReadStatusFailureAsError(s Scanner, req string) error {
status, err := s.ReadStatus()
if err != nil {
return fmt.Errorf("error reading status for %s: %+v", req, err)
}
if !status.IsSuccess() {
msg, err := s.ReadMessage()
if err != nil {
return fmt.Errorf("server returned error for %s, but couldn't read the error message: %+v", err)
}
return &AdbError{
Request: req,
ServerMsg: string(msg),
}
}
return nil
}
// writeFully writes all of data to w. // writeFully writes all of data to w.
// Inverse of io.ReadFully(). // Inverse of io.ReadFully().