clean up indentation and spacing
[supercollider.git] / SCClassLibrary / Common / Core / Error.sc
blobe6e4318d4b8e0ab7ef6195c00f58e778bd9b5a75
1 Exception {
2         classvar <>handling = false;
3         classvar <>debug = false;
4         classvar <>inProtectedFunction = false;
6         var <>what, <>protectedBacktrace, <>path;
8         *new { arg what;
9                 var protectedBacktrace, instance;
10                 if (debug || inProtectedFunction, {
11                         protectedBacktrace = this.getBackTrace.caller;
12                         inProtectedFunction = false;
13                 });
14                 ^super.newCopyArgs(what ? this.name, protectedBacktrace, thisProcess.nowExecutingPath);
15         }
16         errorString {
17                 ^"EXCEPTION: " ++ what
18         }
19         reportError {
20                 this.errorString.postln;
21                 if(protectedBacktrace.notNil, { this.postProtectedBacktrace });
22                 this.dumpBackTrace;
23                 this.adviceLink.postln;
24         }
25         adviceLink {
26                 ^("For advice: [http://supercollider.sf.net/wiki/index.php/%]"
27                         .format(this.adviceLinkPage));
28         }
29         adviceLinkPage {
30                 ^this.errorString.tr($ , $_).tr($\n, $_);
31         }
32         postProtectedBacktrace {
33                 var out, currentFrame, def, ownerClass, methodName, pos;
34                 out = CollStream.new;
35                 "\nPROTECTED CALL STACK:".postln;
36                 currentFrame = protectedBacktrace;
37                 while({currentFrame.notNil}, {
38                         def = currentFrame.functionDef;
39                         if(def.isKindOf(Method), {
40                                 ownerClass = def.ownerClass;
41                                 methodName = def.name;
42                                 if(ownerClass == Function && { #['protect', 'try'].includes(methodName) }, {
43                                         pos = out.pos;
44                                 });
45                                 out << "\t%:%\t%\n".format(ownerClass, methodName, currentFrame.address);
46                         }, {
47                                 out << "\ta FunctionDef\t%\n".format(currentFrame.address);
48                                 out << "\t\tsourceCode = %\n".format(def.sourceCode ? "<an open Function>");
49                         });
50                         def.argNames.do({|name, i|
51                                 out << "\t\targ % = %\n".format(name, currentFrame.args[i]);
52                         });
53                         def.varNames.do({|name, i|
54                                 out << "\t\tvar % = %\n".format(name, currentFrame.vars[i]);
55                         });
56                         currentFrame = currentFrame.caller;
57                 });
58                 // lose everything after the last Function:protect
59                 // it just duplicates the normal stack with less info
60                 // but, an Error in a routine in a Scheduler
61                 // may not have a try/protect in the protectedBacktrace
62                 // then, pos is nil and we should print everything
63                 postln(
64                         if(pos.notNil) {
65                                 out.collection.copyFromStart(pos)
66                         } {
67                                 out.collection
68                         }
69                 );
70         }
72         isException { ^true }
75 Error : Exception {
76         errorString {
77                 ^"ERROR: " ++ what
78         }
79         errorPathString {
80                 ^if(path.isNil) { "" } { "PATH:" + path ++ "\n" }
81         }
84 MethodError : Error {
85         var <>receiver;
87         *new { arg what, receiver;
88                 ^super.new(what).receiver_(receiver)
89         }
90         reportError {
91                 this.errorString.postln;
92                 "RECEIVER:\n".post;
93                 receiver.dump;
94                 this.errorPathString.post;
95                 if(protectedBacktrace.notNil, { this.postProtectedBacktrace });
96                 this.dumpBackTrace;
97                 this.adviceLink.postln;
98         }
99         adviceLinkPage {
100                 ^this.class.name
101         }
105 PrimitiveFailedError : MethodError {
106         var <>failedPrimitiveName;
108         *new { arg receiver;
109                 ^super.new(Thread.primitiveErrorString, receiver)
110                         .failedPrimitiveName_(thisThread.failedPrimitiveName)
111         }
112         errorString {
113                 ^"ERROR: Primitive '%' failed.\n%".format(failedPrimitiveName, what ? "")
114         }
117 SubclassResponsibilityError : MethodError {
118         var <>method, <>class;
119         *new { arg receiver, method, class;
120                 ^super.new(nil, receiver).method_(method).class_(class)
121         }
122         errorString {
123                 ^"ERROR: '" ++ method.name ++ "' should have been implemented by "
124                         ++ class.name ++ "."
125         }
128 ShouldNotImplementError : MethodError {
129         var <>method, <>class;
130         *new { arg receiver, method, class;
131                 ^super.new(nil, receiver).method_(method).class_(class)
132         }
133         errorString {
134                 ^"ERROR: '" ++ method.ownerClass.name ++ "-" ++ method.name
135                         ++ "' Message not valid for this subclass: "
136                         ++ class.name ++ "."
137         }
140 DoesNotUnderstandError : MethodError {
141         var <>selector, <>args;
142         *new { arg receiver, selector, args;
143                 ^super.new(nil, receiver).selector_(selector).args_(args)
144         }
145         errorString {
146                 ^"ERROR: Message '" ++ selector ++ "' not understood."
147         }
148         reportError {
149                 this.errorString.postln;
150                 "RECEIVER:\n".post;
151                 receiver.dump;
152                 "ARGS:\n".post;
153                 args.dumpAll;
154                 this.errorPathString.post;
155                 if(protectedBacktrace.notNil, { this.postProtectedBacktrace });
156                 this.dumpBackTrace;
157                 this.adviceLink.postln;
158         }
159         adviceLinkPage {
160                 ^"%#%".format(this.class.name, selector)
161         }
165 MustBeBooleanError : MethodError {
166         errorString {
167                 ^"ERROR: Non Boolean in test."
168         }
171 NotYetImplementedError : MethodError {
174 OutOfContextReturnError : MethodError {
175         var <>method, <>result;
176         *new { arg receiver, method, result;
177                 ^super.new(nil, receiver).method_(method).result_(result)
178         }
179         errorString {
180                 ^"ERROR: '" ++ method.ownerClass.name ++ "-" ++ method.name
181                         ++ "' Out of context return of value: " ++ result
182         }
185 ImmutableError : MethodError {
186         var <>value;
187         *new { arg receiver, value;
188                 ^super.new(nil, receiver).value_(value)
189         }
190         errorString {
191                 ^"ERROR: Object is immutable: " ++ receiver
192         }
195 BinaryOpFailureError : DoesNotUnderstandError {
196         errorString {
197                 ^"ERROR: binary operator '" ++ selector ++ "' failed."
198         }
201 DeprecatedError : MethodError {
202         var <>method, <>class, <>alternateMethod;
204         *new { arg receiver, method, alternateMethod, class;
205                 ^super.new(nil).receiver_(receiver).method_(method).class_(class).alternateMethod_(alternateMethod)
206         }
207         errorString {
208                 var methodSignature = { arg m;
209                         var c = m.ownerClass;
210                         var str = c.name.asString;
211                         if(c.isMetaClass)
212                                 { str = str.drop( str.indexOf($_) + 1 ) ++ ":*" ++ m.name }
213                                 { str = str ++ ":-" ++ m.name };
214                         str;
215                 };
216                 var searchForCaller = { arg backtrace, m;
217                         while {
218                                 backtrace.notNil and: {
219                                         backtrace.functionDef !== m
220                                 }
221                         } {
222                                 backtrace = backtrace.caller;
223                         };
224                         // backtrace.caller may now be a FunctionDef,
225                         // useless for troubleshooting
226                         // so roll back to the last real method
227                         while {
228                                 backtrace.notNil and: {
229                                         backtrace = backtrace.caller;
230                                         backtrace.functionDef.isKindOf(Method).not
231                                 }
232                         };
233                         if(backtrace.notNil) { backtrace.tryPerform(\functionDef) };
234                 };
235                 var caller, string;
236                 if(protectedBacktrace.notNil) {
237                         caller = searchForCaller.value(protectedBacktrace, method);
238                 };
239                 if(caller.isNil) {
240                         caller = searchForCaller.value(this.getBackTrace, method);
241                 };
242                 if(caller.isNil) {
243                         caller = "{unknown}"
244                 } {
245                         if(caller.isKindOf(Method)) {
246                                 caller = methodSignature.value(caller);
247                         } {
248                                 caller = caller.asString;
249                         };
250                 };
251                 string = "WARNING: Called from %, method % is deprecated and will be removed.".format(
252                         caller,
253                         methodSignature.value(method)
254                 );
255                 if(alternateMethod.notNil, {
256                         string = string + "Use" + methodSignature.value(alternateMethod) + "instead.";
257                 });
258                 ^string;
259         }
261         reportError {
262                 this.errorString.postln;
263                 this.errorPathString.post;
264                 this.adviceLink.postln;
265         }
267         throw {
268                 Error.handling = true;
269                 this.reportError;
270                 if (Error.debug) {
271                         if(protectedBacktrace.notNil, { this.postProtectedBacktrace });
272                         this.dumpBackTrace;
273                         Error.handling = false;
274                         this.halt;
275                 } {
276                         Error.handling = false;
277                 };
279         }
280         adviceLinkPage {
281                 ^"DeprecatedError"
282         }