mito
mito copied to clipboard
Proposal to check early for null values (on `find-dao` and friends)
Hi,
When I call find-dao 'my-model :my-slot (get-data)
but (get-data)
is buggy and returns NIL instead of a value, I get a large stacktrace which goes down to SXQL:
There is no primary method for the generic function
#<STANDARD-GENERIC-FUNCTION SXQL.SQL-TYPE:YIELD (58)>
when called with arguments
(NIL).
[Condition of type SB-PCL::NO-PRIMARY-METHOD-ERROR]
See also:
Common Lisp Hyperspec, 7.6.6.2 [:section]
Restarts:
0: [RETRY] Retry calling the generic function.
1: [RETRY] Retry SLIME REPL evaluation request.
2: [*ABORT] Return to SLIME's top level.
3: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1005F41B63}>)
Backtrace:
0: ((:METHOD SB-PCL::NO-PRIMARY-METHOD (T)) #<STANDARD-GENERIC-FUNCTION SXQL.SQL-TYPE:YIELD (58)> NIL) [fast-method]
1: (SB-PCL::CALL-NO-PRIMARY-METHOD #<STANDARD-GENERIC-FUNCTION SXQL.SQL-TYPE:YIELD (58)> (NIL))
2: ((:METHOD SXQL.SQL-TYPE:YIELD (SXQL.SQL-TYPE:INFIX-OP)) #<error printing object>) [fast-method]
3: ((:METHOD SXQL.SQL-TYPE:YIELD :AROUND (T)) #<error printing object>) [fast-method]
4: ((:METHOD SXQL.SQL-TYPE:YIELD (SXQL.SQL-TYPE:CONJUNCTIVE-OP)) #<error printing object>) [fast-method]
5: ((:METHOD SXQL.SQL-TYPE:YIELD :AROUND (T)) #<error printing object>) [fast-method]
6: ((:METHOD SXQL.SQL-TYPE:YIELD (SXQL.SQL-TYPE:CONJUNCTIVE-OP)) #<error printing object>) [fast-method]
7: ((:METHOD SXQL.SQL-TYPE:YIELD :AROUND (T)) #<error printing object>) [fast-method]
8: ((:METHOD SXQL.SQL-TYPE:YIELD (SXQL.SQL-TYPE:EXPRESSION-CLAUSE)) #<error printing object>) [fast-method]
9: ((:METHOD SXQL.SQL-TYPE:YIELD :AROUND (T)) #<error printing object>) [fast-method]
10: ((:METHOD SXQL.SQL-TYPE:YIELD (SXQL.SQL-TYPE:SQL-COMPOSED-STATEMENT)) #<error printing object>) [fast-method]
11: ((:METHOD SXQL.SQL-TYPE:YIELD (SXQL.STATEMENT:SELECT-STATEMENT)) #<error printing object>) [fast-method]
12: ((SB-PCL::EMF SXQL.SQL-TYPE:YIELD) #<error printing object>)
13: ((:METHOD MITO.DB:RETRIEVE-BY-SQL (SXQL.SQL-TYPE:SQL-STATEMENT)) #<error printing object>) [fast-method]
14: ((SB-PCL::EMF MITO.DB:RETRIEVE-BY-SQL) #<error printing object>)
15: (MITO.DAO:SELECT-BY-SQL #<error printing object>)
16: (MITO.DAO:FIND-DAO #<MITO.DAO.TABLE:DAO-TABLE-CLASS FEL/MODELS::AUTHOR> :ISNI NIL)
17: (MAKE-CARD-FROM-DICT #<HASH-TABLE :TEST EQUAL :COUNT 31 {1002316D93}> :DB-SAVE NIL :FORCE T)
18: (SB-INT:SIMPLE-EVAL-IN-LEXENV (MAKE-CARD-FROM-DICT *CARD* :FORCE T) #<NULL-LEXENV>)
I propose to check early for null values in find-dao
(and friends) to get a smaller stacktrace like this one:
The value for the slot :ISNI should not be null (NIL)
[Condition of type SIMPLE-ERROR]
Restarts:
0: [RETRY] Retry SLIME REPL evaluation request.
1: [*ABORT] Return to SLIME's top level.
2: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1005F41B63}>)
Backtrace:
0: (MITO.DAO::WHERE-AND (:ISNI NIL) #<MITO.DAO.TABLE:DAO-TABLE-CLASS FEL/MODELS::AUTHOR>)
1: (MITO.DAO:FIND-DAO #<MITO.DAO.TABLE:DAO-TABLE-CLASS FEL/MODELS::AUTHOR> :ISNI NIL)
2: (MAKE-CARD-FROM-DICT #<HASH-TABLE :TEST EQUAL :COUNT 31 {1002316D93}> :DB-SAVE NIL :FORCE T)
3: (SB-INT:SIMPLE-EVAL-IN-LEXENV (MAKE-CARD-FROM-DICT *CARD* :FORCE T) #<NULL-LEXENV>)
I got this by adding this check in the where-and
function:
unless slot
do (error "Class ~S does not have a slot named ~S" class field)
unless value ;; <-- added
do (error "The value for the slot ~S should not be null (~S)" field value)
What do you think and how to check this in select-dao
(it doesn't use where-and)?
Best,