jmoiron / modl

golang database modelling library
MIT License
479 stars 48 forks source link

panic if table doesn't exist #18

Closed bsr203 closed 10 years ago

bsr203 commented 10 years ago

As far as I see, any operation results in a panic if the table is not added to dbmap. But, it should either give a clear error about which table is missing, or instead return an error.

stack indicates this line in the code.

func (m *DbMap) TableForType(t reflect.Type) *TableMap {
    for _, table := range m.tables {   // <<== panic at line 389
        if table.gotype == t {
            return table
        }
    }
    return nil
}

stack:

/Users/xxx/repo/go/src/pkg/runtime/panic.c:248 (0x14ca6)
    panic: runtime·newstackcall(d->fn, (byte*)d->args, d->siz);
/Users/xxx/repo/go/src/pkg/runtime/panic.c:482 (0x1554d)
    panicstring: runtime·panic(err);
/Users/xxx/repo/go/src/pkg/runtime/os_darwin.c:450 (0x1444a)
    sigpanic: runtime·panicstring("invalid memory address or nil pointer dereference");
/Users/xxx/repo/server/src/github.com/jmoiron/modl/dbmap.go:389 (0xeb173)
    com/jmoiron/modl.(*DbMap).TableForType: for _, table := range m.tables {
/Users/xxx/repo/server/src/github.com/jmoiron/modl/dbmap.go:382 (0xeb113)
    com/jmoiron/modl.(*DbMap).TableFor: return m.TableForType(t)
/Users/xxx/repo/server/src/github.com/jmoiron/modl/modl.go:250 (0xeda04)
    com/jmoiron/modl.get: table := m.TableFor(dest)
/Users/xxx/repo/server/src/github.com/jmoiron/modl/dbmap.go:309 (0xeac50)
    com/jmoiron/modl.(*DbMap).Get: return get(m, m, dest, keys...)
jmoiron commented 10 years ago

It looks to me like the map is nil. If the table is not returned, then the *TableMap returned is nil and not safe to use (this is kind of bad, by the way; this function should probably return (*TableMap, error).. but that's a breaking change and another discussion).

Your error comes from having a nil DbMap, eg:

type mytable struct{}
myt := mytable{}
var db *DbMap
db.TableForType(reflect.TypeOf(myt))  // m will be nil, so m.tables panics on 389