1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
|
title:: 22_Runtime_errors
summary:: Mark Polishook tutorial
categories:: Tutorials>Mark_Polishook_tutorial
related:: Tutorials/Mark_Polishook_tutorial/00_Introductory_tutorial
section::Runtime errors
Runtime errors occur while a program is executing.
section::Common errors
numberedList::
## an object receives a message which it doesn't understand
## a binary operation (addition, subtraction, multiplication, etc.) can't be performed
## a value other than true or false appears in a conditional (boolean) test
## a file can't be opened (a primitive fails)
::
section::Object doesn't understand
In the case of
code::
3.createRuntimeError
::
SuperCollider prints a four-part error notification to the post window. The parts of the notification are ERROR, RECEIVER, ARGS, and CALL STACK, as in
code::
ERROR: Message 'createRuntimeError' not understood.
RECEIVER:
Integer 3
ARGS:
Instance of Array { (057E7560, gc=01, fmt=01, flg=11, set=00)
indexed slots [0]
}
CALL STACK:
DoesNotUnderstandError-reportError
arg this = <instance of DoesNotUnderstandError>
Nil-handleError
arg this = nil
arg error = <instance of DoesNotUnderstandError>
Object-throw
arg this = <instance of DoesNotUnderstandError>
Object-doesNotUnderstand
arg this = 3
arg selector = 'createRuntimeError'
arg args = [*0]
< closed FunctionDef > (no arguments or variables)
Interpreter-interpretPrintCmdLine
arg this = <instance of Interpreter>
var res = nil
var func = <instance of Function>
Process-interpretPrintCmdLine
arg this = <instance of Main>
::
////////////////////////////////////////////////////////////////////////////////////////////////////
The ERROR section explains what went wrong. The RECEIVER section names the the class of the object to which the message was sent. The ARGS section says how many arguments were included in the message. Read the CALL STACK from the bottom to the top to see where the error happened. Reading from bottom to top means going from
code::
Process-interpretPrintCmdLine
::
to
code::
Interpreter-interpretPrintCmdLine
::
to
code::
Object-doesNotUnderstand
::
to
code::
Object-throw
::
to
code::
Nil-handleError
::
to
code::
DoesNotUnderstandError-reportError
::
which is the first line in the stack.
////////////////////////////////////////////////////////////////////////////////////////////////////
code::
DoesNotUnderstandError-reportError
::
is the mechanism that prints the error notification to the post window. Select it and press cmd-j to see how it works (how it prints the notification).
////////////////////////////////////////////////////////////////////////////////////////////////////
Execute
code::
$a * $b
::
to create another runtime error message.
////////////////////////////////////////////////////////////////////////////////////////////////////
The ERROR, RECEIVER, ARGS, and CALL STACK headers in the post window explain the problem: Instances of class Char have no knowledge of multiplication.
code::
ERROR: Message '*' not understood.
RECEIVER:
Character 97 'a'
ARGS:
Instance of Array { (067F5470, gc=C4, fmt=01, flg=00, set=01)
indexed slots [1]
0 : Character 98 'b'
}
CALL STACK:
DoesNotUnderstandError-reportError
arg this = <instance of DoesNotUnderstandError>
Nil-handleError
arg this = nil
arg error = <instance of DoesNotUnderstandError>
Object-throw
arg this = <instance of DoesNotUnderstandError>
Object-doesNotUnderstand
arg this = $a
arg selector = '*'
arg args = [*1]
< closed FunctionDef > (no arguments or variables)
Interpreter-interpretPrintCmdLine
arg this = <instance of Interpreter>
var res = nil
var func = <instance of Function>
Process-interpretPrintCmdLine
arg this = <instance of Main>
::
section::Unitialized variable (binary operation fails)
Here, the variable a is initialized to an integer and the variable b isn't initialized. Multiplying a (the integer 10) by b (nil, the value that SuperCollider uses for unitialized data) will create a runtime error.
code::
(
var a = 10; // a is declared and initialized
var b; // b declared but not initialized, so it defaults to nil
t = Task({
4.do({ arg item, i;
if(i != 3)
{ i.postln } // print the value of i if it doesn't equal 3
{ (a * b).postln }; // when i equals 3, do a * b
// ... which is a problem if b is nil
1.wait;
})
});
t.start;
)
::
////////////////////////////////////////////////////////////////////////////////////////////////////
The printout shows the code ran successfully until the index, i, reached 3, which is when a * b happened. The ERROR, RECEIVER, ARGS, and CALL STACK headers describe the problem.
////////////////////////////////////////////////////////////////////////////////////////////////////
code::
a Task
0
1
2
ERROR: binary operator '*' failed.
RECEIVER:
nil
ARGS:
Instance of Array { (067D92B0, gc=CC, fmt=01, flg=00, set=01)
indexed slots [2]
0 : Integer 10
1 : nil
}
CALL STACK:
DoesNotUnderstandError-reportError
arg this = <instance of BinaryOpFailureError>
Nil-handleError
arg this = nil
arg error = <instance of BinaryOpFailureError>
Object-throw
arg this = <instance of BinaryOpFailureError>
Object-performBinaryOpOnSomething
arg this = nil
arg aSelector = '*'
arg thing = 10
arg adverb = nil
Integer-*
arg this = 10
arg aNumber = nil
arg adverb = nil
< FunctionDef in closed FunctionDef >
arg item = 3
arg i = 3
Integer-do
arg this = 4
arg function = <instance of Function>
var i = 3
< FunctionDef in closed FunctionDef > (no arguments or variables)
Routine-prStart
arg this = <instance of Routine>
arg inval = 758.000000
::
////////////////////////////////////////////////////////////////////////////////////////////////////
section::True, false, or other
A value other than true or false in a boolean test, as in
code::
if(x=4) { "this is ok"};
::
produces
code::
ERROR: Non Boolean in test.
RECEIVER:
Integer 4
CALL STACK:
MethodError-reportError
arg this = <instance of MustBeBooleanError>
Nil-handleError
arg this = nil
arg error = <instance of MustBeBooleanError>
Object-throw
arg this = <instance of MustBeBooleanError>
Object-mustBeBoolean
arg this = 4
< closed FunctionDef > (no arguments or variables)
Interpreter-interpretPrintCmdLine
arg this = <instance of Interpreter>
var res = nil
var func = <instance of Function>
Process-interpretPrintCmdLine
arg this = <instance of Main>
::
////////////////////////////////////////////////////////////////////////////////////////////////////
Correcting the test clause fixes the problem.
code::
if(x==4) { "this is ok"};
::
////////////////////////////////////////////////////////////////////////////////////////////////////
section::Primitive fails
Asking for the length of a non-existent file creates a runtime error. The notification shows what went wrong (a C code primitive failed).
code::
f = File("i_don't_exist", "r");
f.length;
ERROR: Primitive '_FileLength' failed.
Failed.
RECEIVER:
Instance of File { (067D9970, gc=C4, fmt=00, flg=00, set=01)
instance variables [1]
fileptr : nil
}
CALL STACK:
MethodError-reportError
arg this = <instance of PrimitiveFailedError>
Nil-handleError
arg this = nil
arg error = <instance of PrimitiveFailedError>
Object-throw
arg this = <instance of PrimitiveFailedError>
Object-primitiveFailed
arg this = <instance of File>
File-length
arg this = <instance of File>
< closed FunctionDef > (no arguments or variables)
Interpreter-interpretPrintCmdLine
arg this = <instance of Interpreter>
var res = nil
var func = <instance of Function>
Process-interpretPrintCmdLine
arg this = <instance of Main>
::
////////////////////////////////////////////////////////////////////////////////////////////////////
|