Commit e67326dc authored by gwenn's avatar gwenn

Improves error handling.

parent b034ade0
...@@ -117,7 +117,7 @@ func (c *FunctionContext) Result(r interface{}) { ...@@ -117,7 +117,7 @@ func (c *FunctionContext) Result(r interface{}) {
case Errno: case Errno:
c.ResultErrorCode(r) c.ResultErrorCode(r)
default: default:
panic(fmt.Sprintf("unsupported type in Result: %s", reflect.TypeOf(r))) panic(fmt.Sprintf("unsupported type in Result: %q", reflect.TypeOf(r)))
} }
} }
......
...@@ -30,9 +30,9 @@ import ( ...@@ -30,9 +30,9 @@ import (
type ConnError struct { type ConnError struct {
c *Conn c *Conn
code Errno code Errno // thread safe error code
msg string msg string // it might be the case that a second error occurs on a separate thread in between the time of the first error and the call to retrieve this message.
details string details string // contextual informations, thread safe
} }
func (e *ConnError) Code() Errno { func (e *ConnError) Code() Errno {
...@@ -51,9 +51,9 @@ func (e *ConnError) Filename() string { ...@@ -51,9 +51,9 @@ func (e *ConnError) Filename() string {
func (e *ConnError) Error() string { // FIXME code.Error() & e.msg are often redundant... func (e *ConnError) Error() string { // FIXME code.Error() & e.msg are often redundant...
if len(e.details) > 0 { if len(e.details) > 0 {
return fmt.Sprintf("%s; %s (%s)", e.code.Error(), e.msg, e.details) return fmt.Sprintf("%s (%s) (%s)", e.msg, e.details, e.code.Error())
} else if len(e.msg) > 0 { } else if len(e.msg) > 0 {
return fmt.Sprintf("%s; %s", e.code.Error(), e.msg) return fmt.Sprintf("%s (%s)", e.msg, e.code.Error())
} }
return e.code.Error() return e.code.Error()
} }
...@@ -66,7 +66,7 @@ func (e Errno) Error() string { ...@@ -66,7 +66,7 @@ func (e Errno) Error() string {
if e == ErrSpecific { if e == ErrSpecific {
s = "Wrapper specific error" s = "Wrapper specific error"
} else { } else {
s = C.GoString(C.sqlite3_errstr(C.int(e))) s = C.GoString(C.sqlite3_errstr(C.int(e))) // thread safe
} }
if s == "" { if s == "" {
return fmt.Sprintf("errno %d", int(e)) return fmt.Sprintf("errno %d", int(e))
...@@ -297,7 +297,7 @@ func (c *Conn) Readonly(dbName string) (bool, error) { ...@@ -297,7 +297,7 @@ func (c *Conn) Readonly(dbName string) (bool, error) {
defer C.free(unsafe.Pointer(cname)) defer C.free(unsafe.Pointer(cname))
rv := C.sqlite3_db_readonly(c.db, cname) rv := C.sqlite3_db_readonly(c.db, cname)
if rv == -1 { if rv == -1 {
return false, c.error(C.SQLITE_ERROR, fmt.Sprintf("%q is not the name of a database", dbName)) return false, c.specificError("%q is not the name of a database", dbName)
} }
return rv == 1, nil return rv == 1, nil
} }
......
...@@ -196,7 +196,7 @@ func TestConnExecWithSelect(t *testing.T) { ...@@ -196,7 +196,7 @@ func TestConnExecWithSelect(t *testing.T) {
err := db.Exec("SELECT 1") err := db.Exec("SELECT 1")
assert.T(t, err != nil, "error expected") assert.T(t, err != nil, "error expected")
if serr, ok := err.(*StmtError); ok { if serr, ok := err.(*StmtError); ok {
assert.Equal(t, Row, serr.Code()) assert.Equal(t, ErrSpecific, serr.Code())
} else { } else {
t.Errorf("Expected StmtError but got %s", reflect.TypeOf(err)) t.Errorf("Expected StmtError but got %s", reflect.TypeOf(err))
} }
...@@ -244,6 +244,7 @@ func TestExecMisuse(t *testing.T) { ...@@ -244,6 +244,7 @@ func TestExecMisuse(t *testing.T) {
createTable(db, t) createTable(db, t)
err := db.Exec("INSERT INTO test VALUES (?, ?, ?, ?); INSERT INTO test VALUES (?, ?, ?, ?)", 0, 273.1, 1, "test") err := db.Exec("INSERT INTO test VALUES (?, ?, ?, ?); INSERT INTO test VALUES (?, ?, ?, ?)", 0, 273.1, 1, "test")
assert.T(t, err != nil, "exec misuse expected") assert.T(t, err != nil, "exec misuse expected")
//println(err.Error())
} }
func TestTransaction(t *testing.T) { func TestTransaction(t *testing.T) {
......
...@@ -159,7 +159,7 @@ func (s *Stmt) exec() error { ...@@ -159,7 +159,7 @@ func (s *Stmt) exec() error {
err := Errno(rv) err := Errno(rv)
if err != Done { if err != Done {
if err == Row { if err == Row {
return s.error(rv, "Don't use exec with anything that returns data such as SELECT") return s.specificError("Don't use exec with anything that returns data such as SELECT")
} }
return s.error(rv, "Stmt.exec") return s.error(rv, "Stmt.exec")
} }
...@@ -603,7 +603,7 @@ func (s *Stmt) ColumnIndex(name string) (int, error) { ...@@ -603,7 +603,7 @@ func (s *Stmt) ColumnIndex(name string) (int, error) {
if ok { if ok {
return index, nil return index, nil
} }
return -1, s.specificError("invalid column name: %s", name) return -1, s.specificError("invalid column name: %q", name)
} }
// ScanByName scans result value from a query. // ScanByName scans result value from a query.
...@@ -1059,14 +1059,14 @@ func (s *Stmt) checkTypeMismatch(source, target Type) error { ...@@ -1059,14 +1059,14 @@ func (s *Stmt) checkTypeMismatch(source, target Type) error {
case Text: case Text:
fallthrough fallthrough
case Blob: case Blob:
return s.specificError("type mismatch, source %s vs target %s", source, target) return s.specificError("type mismatch, source %q vs target %q", source, target)
} }
case Float: case Float:
switch source { switch source {
case Text: case Text:
fallthrough fallthrough
case Blob: case Blob:
return s.specificError("type mismatch, source %s vs target %s", source, target) return s.specificError("type mismatch, source %q vs target %q", source, target)
} }
} }
return nil return nil
......
...@@ -137,6 +137,7 @@ func TestNamedScanColumn(t *testing.T) { ...@@ -137,6 +137,7 @@ func TestNamedScanColumn(t *testing.T) {
_, err = s.ScanByName("invalid", &i1) _, err = s.ScanByName("invalid", &i1)
assert.T(t, err != nil, "expected invalid name") assert.T(t, err != nil, "expected invalid name")
//println(err.Error())
} }
func TestScanCheck(t *testing.T) { func TestScanCheck(t *testing.T) {
...@@ -270,8 +271,9 @@ func TestStmtExecWithSelect(t *testing.T) { ...@@ -270,8 +271,9 @@ func TestStmtExecWithSelect(t *testing.T) {
err = s.Exec() err = s.Exec()
assert.T(t, err != nil, "error expected") assert.T(t, err != nil, "error expected")
//println(err.Error())
if serr, ok := err.(*StmtError); ok { if serr, ok := err.(*StmtError); ok {
assert.Equal(t, Row, serr.Code()) assert.Equal(t, ErrSpecific, serr.Code())
} else { } else {
t.Errorf("Expected StmtError but got %s", reflect.TypeOf(err)) t.Errorf("Expected StmtError but got %s", reflect.TypeOf(err))
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment