~ubuntu-branches/ubuntu/karmic/gnustep-base/karmic

« back to all changes in this revision

Viewing changes to Documentation/manual/ExceptionHandling.texi

  • Committer: Bazaar Package Importer
  • Author(s): Eric Heintzmann
  • Date: 2005-04-17 00:14:38 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050417001438-enf0y07c9tku85z1
Tags: 1.10.3-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
@paragraphindent 0
 
2
 
 
3
@node Exception Handling
 
4
@chapter Exception Handling, Logging, and Assertions
 
5
@cindex exception facilities
 
6
@cindex logging facilities
 
7
@cindex assertion facilities
 
8
 
 
9
No matter how well a program is designed, if it has to interact with a user or
 
10
other aspect of the outside world in any way, the code is bound to
 
11
occasionally meet with cases that are either invalid or just plain unexpected.
 
12
A very simple example is when a program asks the user to enter a filename, and
 
13
the user enters the name of a file that does not exist, or does not enter a
 
14
name at all.  Perhaps a valid filename @i{is} entered, but, due to a previous
 
15
disk write error the contents are garbled.  Any number of things can go wrong.
 
16
In addition, programmer error inevitably occurs and needs to be taken account
 
17
of.  Internal functions may be called with invalid arguments, either due to
 
18
unexpected paths being taken through the code, or silly things like typos
 
19
using the wrong variable for something.  When these problems happen (and they
 
20
@i{will} happen), it is better to handle them gracefully than for the program
 
21
to crash, or worse, to continue processing but in an erroneous way.
 
22
 
 
23
To allow for this, many computer languages provide two types of facilities.
 
24
The first is referred to as @i{exception handling} or sometimes @i{error
 
25
trapping}.  The second is referred to as @i{assertion checking}.  Exceptions
 
26
allow the program to catch errors when they occur and react to them
 
27
explicitly.  Assertions allow a programmer to establish that certain
 
28
conditions hold before attempting to execute a particular operation.  GNUstep
 
29
provides both of these facilities, and we will cover each in turn.  The
 
30
assertion facility is tied in with the GNUstep @i{logging} facilities, so we
 
31
describe those as well.
 
32
 
 
33
To use any of the facilities described in this chapter requires that you
 
34
include @code{Foundation/NSException.h}.
 
35
 
 
36
 
 
37
@section Exceptions
 
38
@cindex exceptions
 
39
@cindex NSException class
 
40
@cindex NS_DURING macro
 
41
@cindex NS_HANDLER macro
 
42
@cindex NS_ENDHANDLER macro
 
43
@cindex NSUncaughtExceptionHandler
 
44
 
 
45
GNUstep exception handling provides for two things:
 
46
 
 
47
@enumerate
 
48
@item
 
49
When an error condition is detected during execution, control is passed to a
 
50
special error-handling routine, which is given information on the error that
 
51
occurred.
 
52
@item
 
53
This routine may itself, if it chooses, pass this information up the function
 
54
call stack to the next higher level of control.  Often higher level code is
 
55
more aware of the context in which the error is occurring, and can therefore
 
56
make a better decision as to how to react.
 
57
@end enumerate
 
58
 
 
59
 
 
60
@subsection Catching and Handling Exceptions
 
61
 
 
62
GNUstep exception handling is implemented through the macros @code{NS_DURING},
 
63
@code{NS_HANDLER}, and @code{NS_ENDHANDLER} in conjunction with the
 
64
@code{NSException} class.  The following illustrates the pattern:
 
65
 
 
66
@example
 
67
NS_DURING
 
68
  @{
 
69
    // do something risky ...
 
70
  @}
 
71
NS_HANDLER
 
72
  @{
 
73
    // a problem occurred; inform user or take another tack ...
 
74
  @}
 
75
NS_ENDHANDLER
 
76
  // back to normal code...
 
77
@end example
 
78
 
 
79
For instance:
 
80
 
 
81
@example
 
82
- (DataTree *) readDataFile: (String *)filename
 
83
@{
 
84
  ParseTree *parse = nil;
 
85
  NS_DURING
 
86
    @{
 
87
      FileHandle *handle = [self getFileHandle: filename];
 
88
      parse = [parser parseFile: handle];
 
89
    @}
 
90
  NS_HANDLER
 
91
    @{
 
92
      if ([[localException name] isEqualToString: MyFileNotFoundException])
 
93
        @{
 
94
          NS_VALUERETURN([self readDataFile: fallbackFilename]);
 
95
        @}
 
96
      else if ([[localException name] isEqualToString: NSParseErrorException])
 
97
        @{
 
98
          NS_VALUERETURN([self readDataFileInOldFormat: filename]);
 
99
        @}
 
100
      else
 
101
        @{
 
102
          [localException raise];
 
103
        @}
 
104
    @}
 
105
  NS_ENDHANDLER
 
106
  return [[DataTree alloc] initFromParseTree: parse];
 
107
@}
 
108
@end example
 
109
 
 
110
Here, a file is parsed, with the possibility of at least two different errors:
 
111
not finding the file and the file being misformatted.  If a problem does
 
112
occur, the code in the @code{NS_HANDLER} block is jumped to.  Information on
 
113
the error is passed to this code in the @code{localException} variable, which
 
114
is an instance of @code{NSException}.  The handler code examines the name of
 
115
the exception to determine if it can implement a work-around.  In the first
 
116
two cases, an alternative approach is available, and so the
 
117
@code{NS_VALUERETURN} macro is used to return an alternative value to the
 
118
@code{readDataFile:} caller.  Note that it is @i{not} allowed to simply write
 
119
``@code{return x;}'' inside an exception handler, owing to the nature of the
 
120
behind-the-scenes C constructs implementing the mechanism (the @code{setjmp()}
 
121
and @code{longjmp()} functions).  If you are in a void function not returning
 
122
a value, you may use simply ``@code{NS_VOIDRETURN}'' instead.  Finally, notice
 
123
that in the third case above the handler does not recognize the exception
 
124
type, so it passes it one level up to the caller by calling @code{-raise} on
 
125
the exception object.
 
126
 
 
127
 
 
128
@subsection Passing Exceptions Up the Call Stack
 
129
 
 
130
If the caller of @code{-readDataFile:} has enclosed the call inside its own
 
131
@code{NS_DURING} @dots{} @code{NS_HANDLER} @dots{} @code{NS_ENDHANDLER} block,
 
132
it will be able to catch this exception and react to it in the same way as we
 
133
saw here.  Being at a higher level of execution, it may be able to take
 
134
actions more appropriate than the @code{-readDataFile:} method could have.
 
135
 
 
136
If, on the other hand, the caller had @i{not} enclosed the call, it would not
 
137
get a chance to react, but the exception would be passed up to the caller of
 
138
@i{this} code.  This is repeated until the top control level is reached, and
 
139
then as a last resort @code{NSUncaughtExceptionHandler} is called.  This is a
 
140
built-in function that will print an error message to the console and exit
 
141
the program immediately.  If you don't want this to happen it is possible to
 
142
override this function by calling
 
143
@code{NSSetUncaughtExceptionHandler(fn_ptr)}.  Here, @code{fn_ptr} should be
 
144
the name of a function with this signature (defined in @code{NSException.h}):
 
145
 
 
146
@example
 
147
void NSUncaughtExceptionHandler(NSException *exception);
 
148
@end example
 
149
 
 
150
One possibility would be to use this to save files or any other unsaved state
 
151
before an application exits because of an unexpected error.
 
152
 
 
153
 
 
154
@subsection Where do Exceptions Originate?
 
155
 
 
156
You may be wondering at this point where exceptions come from in the first
 
157
place.  There are two main possibilities.  The first is from the Base library;
 
158
many of its classes raise exceptions when they run into error conditions.  The
 
159
second is that application code itself raises them, as described in the next
 
160
section.  Exceptions do @i{not} arise automatically from C-style error
 
161
conditions generated by C libraries.  Thus, if you for example call the
 
162
@code{strtod()} function to convert a C string to a double value, you still
 
163
need to check @code{errno} yourself in standard C fashion.
 
164
 
 
165
Another case that exceptions are @i{not} raised in is in the course of
 
166
messaging.  If a message is sent to @code{nil}, it is silently ignored
 
167
without error.  If a message is sent to an object that does not implement it,
 
168
the @code{forwardInvocation} method is called instead, as discussed in
 
169
@ref{Advanced Messaging}.
 
170
 
 
171
 
 
172
@subsection Creating Exceptions
 
173
 
 
174
If you want to explicitly create an exception for passing a particular error
 
175
condition upwards to calling code, you may simply create an
 
176
@code{NSException} object and @code{raise} it:
 
177
 
 
178
@example
 
179
NSException myException = [[NSException alloc]
 
180
                              initWithName: @@"My Exception"
 
181
                                    reason: @@"[Description of the cause...]"
 
182
                                  userInfo: nil];
 
183
[myException raise];
 
184
 // code in block after here is unreachable..
 
185
@end example
 
186
 
 
187
The @code{userInfo} argument here is a @code{NSDictionary} of key-value pairs
 
188
containing application-specific additional information about the error.  You
 
189
may use this to pass arbitrary arguments within your application.  (Because
 
190
this is a convenience for developers, it should have been called
 
191
@code{developerInfo}..)
 
192
 
 
193
Alternatively, you can create the exception and raise it in one call with
 
194
@code{+raise}:
 
195
 
 
196
@example
 
197
[NSException raise: @@"My Exception"
 
198
            format: @@"Parse error occurred at line %d.",lineNumber];
 
199
@end example
 
200
 
 
201
Here, the @code{format} argument takes a printf-like format analogous to
 
202
@code{[NSString -stringWithFormat:]} discussed @ref{Objective-C, previously,
 
203
Strings in GNUstep}.  In general, you should not use arbitrary names for
 
204
exceptions as shown here but constants that will be recognized throughout your
 
205
application.  In fact, GNUstep defines some standard constants for this
 
206
purpose in @code{NSException.h}:
 
207
 
 
208
@table @code
 
209
@item NSCharacterConversionException
 
210
An exception when character set conversion fails.
 
211
@item NSGenericException
 
212
A generic exception for general purpose usage.
 
213
@item NSInternalInconsistencyException
 
214
An exception for cases where unexpected state is detected within an object.
 
215
@item NSInvalidArgumentException
 
216
An exception used when an invalid argument is passed to a method or function.
 
217
@item NSMallocException
 
218
An exception used when the system fails to allocate required memory.
 
219
@item NSParseErrorException
 
220
An exception used when some form of parsing fails.
 
221
@item NSRangeException
 
222
An exception used when an out-of-range value is encountered.
 
223
@end table
 
224
 
 
225
Also, some Foundation classes define their own more specialized exceptions:
 
226
 
 
227
@table @code
 
228
@item NSFileHandleOperationException (NSFileHandle.h)
 
229
An exception used when a file error occurs.
 
230
@item NSInvalidArchiveOperationException (NSKeyedArchiver.h)
 
231
An archiving error has occurred.
 
232
@item NSInvalidUnarchiveOperationException (NSKeyedUnarchiver.h)
 
233
An unarchiving error has occurred.
 
234
@item NSPortTimeoutException (NSPort.h)
 
235
Exception raised if a timeout occurs during a port send or receive operation.
 
236
@item NSUnknownKeyException (NSKeyValueCoding.h)
 
237
 An exception for an unknown key.
 
238
@end table
 
239
 
 
240
 
 
241
@subsection When to Use Exceptions
 
242
 
 
243
As might be evident from the @code{-readDataFile:} example above, if a
 
244
certain exception can be anticipated, it can also be checked for, so you
 
245
don't necessarily need the exception mechanism.  You may want to use
 
246
exceptions anyway if it simplifies the code paths.  It is also good practice
 
247
to catch exceptions when it can be seen that an unexpected problem might
 
248
arise, as any time file, network, or database operations are undertaken, for
 
249
instance.
 
250
 
 
251
Another important case where exceptions are useful is when you need to pass
 
252
detailed information up to the calling method so that it can react
 
253
appropriately.  Without the ability to raise an exception, you are limited to
 
254
the standard C mechanism of returning a value that will hopefully be
 
255
recognized as invalid, and perhaps using an @code{errno}-like strategy where
 
256
the caller knows to examine the value of a certain global variable.  This is
 
257
inelegant, difficult to enforce, and leads to the need, with void methods, to
 
258
document that ``the caller should check @code{errno} to see if any problems
 
259
arose''.
 
260
 
 
261
 
 
262
@section Logging
 
263
@cindex logging
 
264
@cindex NSLog function
 
265
@cindex NSDebugLog function
 
266
@cindex NSWarnLog function
 
267
@cindex profiling facilities
 
268
 
 
269
GNUstep provides several distinct logging facilities best suited for different
 
270
purposes.
 
271
 
 
272
@subsection NSLog
 
273
 
 
274
The simplest of these is the @code{NSLog(NSString *format, ...)}  function.
 
275
For example:
 
276
 
 
277
@example
 
278
NSLog(@@"Error occurred reading file at line %d.", lineNumber);
 
279
@end example
 
280
 
 
281
This would produce, on the console (stderr) of the application calling it,
 
282
something like:
 
283
 
 
284
@example
 
285
2004-05-08 22:46:14.294 SomeApp[15495] Error occurred reading file at line 20.
 
286
@end example
 
287
 
 
288
The behavior of this function may be controlled in two ways.  First, the user
 
289
default @code{GSLogSyslog} can be set to ``@code{YES}'', which will send
 
290
these messages to the syslog on systems that support that (Unix variants).
 
291
Second, the function GNUstep uses to write the log messages can be
 
292
overridden, or the file descriptor the existing function writes to can be
 
293
overridden:
 
294
@comment{Need ref to where user defaults are explained.}
 
295
 
 
296
@example
 
297
  // these changes must be enclosed within a lock for thread safety
 
298
NSLock *logLock = GSLogLock();
 
299
[logLock lock];
 
300
 
 
301
  // to change the file descriptor:
 
302
_NSLogDescriptor = <fileDescriptor>;
 
303
  // to change the function itself:
 
304
_NSLog_printf_handler = <functionName>;
 
305
 
 
306
[logLock unlock];
 
307
@end example
 
308
 
 
309
Due to locking mechanisms used by the logging facility, you should protect
 
310
these changes using the lock provided by @code{GSLogLock()} (see @ref{Base
 
311
Library, , Threads and Run Control} on locking).
 
312
 
 
313
The @code{NSLog} function was defined in OpenStep and is also available in Mac
 
314
OS X Cocoa, although the overrides described above may not be.  The next set of
 
315
logging facilities to be described are only available under GNUstep.
 
316
 
 
317
 
 
318
@subsection NSDebugLog, NSWarnLog
 
319
 
 
320
The facilities provided by the @code{NSDebugLog} and @code{NSWarnLog} families
 
321
of functions support source code method name and line-number reporting and
 
322
allow compile- and run-time control over logging level.
 
323
 
 
324
The @code{NSDebugLog} functions are enabled at compile time by default.  To
 
325
turn them off, set @code{'diagnose = no'} in your makefile, or undefine
 
326
@code{GSDIAGNOSE} in your code before including @code{NSDebug.h}.  To turn
 
327
them off at runtime, call @code{[[NSProcessInfo processInfo]
 
328
setDebugLoggingEnabled: NO]}.  (An @code{NSProcessInfo} instance is
 
329
automatically instantiated in a running GNUstep application and may be
 
330
obtained by invoking @code{[NSProcessInfo processInfo]}.)
 
331
 
 
332
At runtime, whether or not logging is enabled, a debug log method is called
 
333
like this:
 
334
 
 
335
@example
 
336
NSDebugLLog(@@"ParseError", @@"Error parsing file at line %d.", lineNumber);
 
337
@end example
 
338
 
 
339
Here, the first argument to @code{NSDebugLog}, ``@code{ParseError}'', is a
 
340
string @i{key} that specifies the category of message.  The message will only
 
341
actually be logged (through a call to @code{NSLog()}) if this key is in the
 
342
set of active debug categories maintained by the @code{NSProcessInfo} object
 
343
for the application.  Normally, this list is empty.  There are
 
344
three ways for string keys to make it onto this list:
 
345
 
 
346
@itemize
 
347
@item
 
348
Provide one or more startup arguments of the form @code{--GNU-Debug=<key>} to
 
349
the program.  These are processed by GNUstep and removed from the argument
 
350
list before any user code sees them.
 
351
@item
 
352
Call @code{[NSProcessInfo debugSet]} at runtime, which returns an
 
353
@code{NSMutableSet}.  You can add (or remove) strings to this set directly.
 
354
@item
 
355
The @code{GNU-Debug} user default nay contain a comma-separated list of keys.
 
356
However, note that @code{[NSUserDefaults standardUserDefaults]} must first be
 
357
called before this will take effect (to read in the defaults initially).
 
358
@end itemize
 
359
 
 
360
While any string can be used as a debug key, conventionally three types of
 
361
keys are commonly used.  The first type expresses a ``level of importance''
 
362
for the message, for example, ``Debug'', ``Info'', ``Warn'', or ``Error''.
 
363
The second type of key that is used is class name.  The GNUstep Base classes
 
364
used this approach.  For example if you want to activate debug messages for
 
365
the @code{NSBundle}'' class, simply add '@code{NSBundle}' to the list of keys.
 
366
The third category of key is the default key, '@code{dflt}'.  This key can be
 
367
used whenever the specificity of the other key types is not required.  Note
 
368
that it still needs to be turned on like any other logging key before
 
369
messasges will actually be logged.
 
370
 
 
371
There is a family of @code{NSDebugLog} functions with slightly differing
 
372
behaviors:
 
373
 
 
374
@table @code
 
375
@item NSDebugLLog(key, format, args,...)
 
376
Basic debug log function already discussed.
 
377
@item NSDebugLog(format, args,...)
 
378
Equivalent to @code{NSDebugLLog} with key ``dflt'' (for default).
 
379
@item NSDebugMLLog(level, format, args,...)
 
380
Equivalent to @code{NSDebugLLog} but includes information on which method the
 
381
logging call was made from in the message.
 
382
@item NSDebugMLog(format, args,...)
 
383
Same, but use 'dflt' log key.
 
384
@item NSDebugFLLog(level, format, args,...)
 
385
As @code{NSDebugMLLog} but includes information on a function rather than a
 
386
method.
 
387
@item NSDebugFLog(format, args,...)
 
388
As previous but using 'dflt' log key.
 
389
@end table
 
390
 
 
391
The implementations of the @code{NSDebugLog} functions are optimized so that
 
392
they consume little time when logging is turned off.  In particular, if debug
 
393
logging is deactivated at compile time, there is NO performance cost, and if
 
394
it is completely deactivated at runtime, each call entails only a boolean
 
395
test.  Thus, they can be left in production code.
 
396
 
 
397
There is also a family of @code{NSWarn} functions.  They are similar to the
 
398
@code{NSDebug} functions except that they do not take a key.  Instead, warning
 
399
messages are shown by default unless they are disabled at compile time by
 
400
setting @code{'warn = no'} or undefining @code{GSWARN}, or at runtime by
 
401
@i{adding} ``@code{NoWarn}'' to @code{[NSProcessInfo debugSet]}.
 
402
(Command-line argument @code{--GNU-Debug=NoWarn} and adding ``NoWarn'' to the
 
403
@code{GNU-Debug} user default will also work.)  @code{NSWarnLog()},
 
404
@code{NSWarnLLog()}, @code{NSWarnMLLog}, @code{NSWarnMLog},
 
405
@code{NSWarnFLLog}, and @code{NSWarnFLog} are all similar to their
 
406
@code{NSDebugLog} counterparts.
 
407
 
 
408
 
 
409
@subsection Last Resorts: GSPrintf and fprintf
 
410
 
 
411
Both the @code{NSDebugLog} and the simpler @code{NSLog} facilities utilize a
 
412
fair amount of machinery - they provide locking and timestamping for example.
 
413
Sometimes this is not appropriate, or might be too heavyweight in a case where
 
414
you are logging an error which might involve the application being in some
 
415
semi-undefined state with corrupted memory or worse.  You can use the
 
416
@code{GSPrintf()} function, which simply converts a format string to UTF-8 and
 
417
writes it to a given file:
 
418
 
 
419
@example
 
420
GSPrintf(stderr, "Error at line %d.", n);
 
421
@end example
 
422
 
 
423
If even this might be too much (it uses the @code{NSString} and @code{NSData}
 
424
classes), you can always use the C function @code{fprintf()}:
 
425
 
 
426
@example
 
427
fprintf(stderr, "Error at line %d.", n);
 
428
@end example
 
429
 
 
430
Except under extreme circumstances, the preferred logging approach is either
 
431
@code{NSDebugLog}/@code{NSWarnLog}, due the the compile- and run-time
 
432
configurability they offer, or @code{NSLog}.
 
433
 
 
434
 
 
435
@subsection Profiling Facilities
 
436
 
 
437
GNUstep supports optional programmatic access to object allocation
 
438
statistics.  To initiate collection of statistics, call the function
 
439
@code{GSDebugAllocationActive(BOOL active)} with an argument of
 
440
``@code{YES}''.  To turn it off, call it with ``@code{NO}''.  The overhead
 
441
of statistics collection is only incurred when it is active.  To access the
 
442
statistics, use the set of @code{GSDebugAllocation...()} functions defined in
 
443
@code{NSDebug.h}.
 
444
 
 
445
 
 
446
@section Assertions
 
447
@cindex assertions
 
448
@cindex NSAssert macro
 
449
@cindex NSAssertionHandler class
 
450
 
 
451
Assertions provide a way for the developer to state that certain conditions
 
452
must hold at a certain point in source code execution.  If the conditions do
 
453
not hold, an exception is automatically raised (and succeeding code in the
 
454
block is not executed).  This avoids an operation from taking place with
 
455
illegal inputs that may lead to worse problems later.
 
456
 
 
457
The use of assertions is generally accepted to be an efficient means of
 
458
improving code quality, for, like unit testing, they can help rapidly uncover
 
459
a developer's implicit or mistaken assumptions about program behavior.
 
460
However this is only true to the extent that you carefully design the nature
 
461
and placement of your assertions.  There is an excellent discussion of this
 
462
issue bundled in the documentation with Sun's Java distribution.
 
463
@comment{Add link to appropriate java.sun.com page.}
 
464
 
 
465
@subsection Assertions and their Handling
 
466
 
 
467
Assertions allow the developer to establish that certain conditions hold
 
468
before undertaking an operation.  In GNUstep, the standard means to make an
 
469
assertion is to use one of a collection of @code{NSAssert} macros.  The
 
470
general form of these macros is:
 
471
 
 
472
@example
 
473
NSAssert(<boolean test>, <formatString>, <argumentsToFormat>);
 
474
@end example
 
475
 
 
476
For instance:
 
477
 
 
478
@example
 
479
NSAssert1(x == 10, "X should have been 10, but it was %d.", x);
 
480
@end example
 
481
 
 
482
If the test '@code{x == 10}' evaluates to @code{true}, @code{NSLog()} is
 
483
called with information on the method and line number of the failure, together
 
484
with the format string and argument.  The resulting console message will look
 
485
like this:
 
486
 
 
487
@example
 
488
Foo.m:126  Assertion failed in Foo(instance), method Bar.  X should have been
 
489
10, but it was 5.
 
490
@end example
 
491
 
 
492
After this is logged, an exception is raised of type
 
493
'@code{NSInternalInconsistencyException}', with this string as its
 
494
description.
 
495
 
 
496
In order to provide the method and line number information, the
 
497
@code{NSAssert()} routine must be implemented as a macro, and therefore to
 
498
handle different numbers of arguments to the format string, there are 5
 
499
assertion macros for methods: @code{NSAssert(condition, description)},
 
500
@code{NSAssert1(condition, format, arg1)}, @code{NSAssert2(condition, format,
 
501
arg1, arg2)}, ..., @code{NSAssert5(...)}.
 
502
 
 
503
If you need to make an assertion inside a regular C function (not an
 
504
Objective-C method), use the equivalent macros @code{NSCAssert()}, etc..
 
505
 
 
506
@i{@b{Note}}, you can completely disable assertions (saving the time for the
 
507
boolean test and avoiding the exception if fails) by putting @code{#define
 
508
NS_BLOCK_ASSERTIONS} before you include @code{NSException.h}.
 
509
 
 
510
 
 
511
@subsection Custom Assertion Handling
 
512
 
 
513
The aforementioned behavior of logging an assertion failure and raising an
 
514
exception can be overridden if desired.  You need to create a subclass of
 
515
@code{NSAssertionHandler} and register an instance in each thread in which
 
516
you wish the handler to be used.  This is done by calling:
 
517
 
 
518
@example
 
519
[[[NSThread currentThread] threadDictionary]
 
520
    setObject:myAssertionHandlerInstance forKey:@"NSAssertionHandler"];
 
521
@end example
 
522
 
 
523
See @ref{Base Library, , Threads and Run Control} for more information on what
 
524
this is doing.
 
525
 
 
526
 
 
527
@section Comparison with Java
 
528
@cindex exception handling, compared with Java
 
529
@cindex logging, compared with Java
 
530
@cindex assertion handling, compared with Java
 
531
 
 
532
GNUstep's exception handling facilities are, modulo syntax, equivalent to
 
533
those in Java in all but three respects:
 
534
 
 
535
@itemize
 
536
@item
 
537
There is no provision for a ``finally'' block executed after either the main
 
538
code or the exception handler code.
 
539
@item
 
540
You cannot declare the exception types that could be raised by a method in its
 
541
signature.  In Java this is possible and the compiler uses this to enforce
 
542
that a caller should catch exceptions if they might be generated by a method.
 
543
@item
 
544
Correspondingly, there is no support in the @ref{GSDoc, documentation system}
 
545
for documenting exceptions potentially raised by a method.  (This will
 
546
hopefully be rectified soon.)
 
547
@end itemize
 
548
 
 
549
The logging facilities provided by @code{NSDebugLog} and company are similar
 
550
to but a bit more flexible than those provided in the Java/JDK 1.4 logging APIs,
 
551
which were based on the IBM/Apache Log4J project.
 
552
 
 
553
The assertion facilities are similar to but a bit more flexible than those in
 
554
Java/JDK 1.4 since you can override the assertion handler.
 
555
 
 
556
@page