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

View file

@ -20,9 +20,6 @@ type DirEntry struct {
type DirEntries struct {
scanner wire.SyncScanner
// Called when finished iterating (successfully or not).
doneHandler func()
currentEntry *DirEntry
err error
}
@ -35,13 +32,13 @@ func (entries *DirEntries) Next() bool {
entry, done, err := readNextDirListEntry(entries.scanner)
if err != nil {
entries.err = err
entries.onDone()
entries.Close()
return false
}
entries.currentEntry = entry
if done {
entries.onDone()
entries.Close()
return false
}
@ -56,10 +53,10 @@ func (entries *DirEntries) Err() error {
return entries.err
}
func (entries *DirEntries) onDone() {
if entries.doneHandler != nil {
entries.doneHandler()
}
// Close closes the connection to the adb.
// Next() will call Close() before returning false.
func (entries *DirEntries) Close() error {
return entries.scanner.Close()
}
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
return
} 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
}
mode, err := s.ReadFileMode()
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
}
size, err := s.ReadInt32()
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
}
mtime, err := s.ReadTime()
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
}
name, err := s.ReadString()
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
}

View file

@ -8,6 +8,11 @@ import (
"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.

View file

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

View file

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

View file

@ -5,17 +5,17 @@ import (
)
type AdbError struct {
Request []byte
Request string
ServerMsg string
}
var _ error = &AdbError{}
func (e *AdbError) Error() string {
if e.Request == nil {
if e.Request == "" {
return fmt.Sprintf("server error: %s", e.ServerMsg)
} 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
}
if err = ReadStatusFailureAsError(conn, req); err != nil {
if err = ReadStatusFailureAsError(conn, string(req)); err != nil {
return nil, err
}

View file

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

View file

@ -87,30 +87,6 @@ func (s *realScanner) NewSyncScanner() SyncScanner {
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 {
return s.reader.Close()
}

View file

@ -1,6 +1,33 @@
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.
// Inverse of io.ReadFully().