This class contains a small set of tools to help in debugging. First is a set of tools to instrument the code each type of instrumentation attempts to address a different type of bug. Any messages go to the Standard output channel. messages come out in the format "<code><tag> message</code>" so they can easily be found. For errors, the tag is pre-populated with "ERROR!", for warnings the tag is user specified. For Status messages, the tag is optional.
Unfortunately, this implementation every Debug method added still costs execution time, regardless if the given verbosity level means no message will be produced. So Debug.pln(lvl, big-complicated-string-operation) means the big string operation will be computed every time, even when the Debug.pln is never triggered.
Each of these debugging messages approximately means
-
Error - Usually indicates a software error. Something where the program is confused. The requested operation will need to be ignored (or perhaps the program must exit).
-
Warning - Usually indicates a condition that should not be reached, but the software can "fix" the situation.
The fix may or may not be the intent, hence the warning.
-
Status - Anything else
The main instrumentation methods are
-
checkError(condition, msg)
If the condition is violated, then the message is output. If the FAIL_FAST flag is true, the program will exit.
-
error(msg)
This method will always display the msg to the console. This should be reserved for true errors, not curious or questionable situations. If the FAIL_FAST flag is true, then this method will force an immediate program exit.
-
checkWarning(condition, tag, msg)
If the condition is violated, then the message is displayed to the console.
-
warning(tag, msg)
Writes the message to the console (in the format described above).
-
pln(tag, msg)
This provides intermediate program state information. If the Debug class is in "verbose" mode, then these messages will be output, if Debug is in "silent" mode, then these messages will be suppressed.
-
pln(msg)
This provides intermediate program state information. Only the message comes out, there is no "tag"
-
pln(msg, verbose)
Same as above, except it does not rely Debug's notion of a verbosity level. If the verbose flag is true, then the message is output.
-
pln(lvl, msg)
This provides information at a user-specified level (>= 2). Only the message comes out, there is no "tag"
-
pln(lvl, tag, msg)
Same as above, along with a user-specified tag.
Usage scenarios
-
Ensure that conditions that should "never happen" truly never happen. Instrument the areas of the code that should never be reached with
checkError
or error
methods. While in development the FAIL_FAST flag should be true. When the software is ready for distribution, it should be set to true. If a field report comes back with unusual behavior, search the log for any messages that start with "<ERROR!>".
-
An external user can't get the software to work. Instruct them to call
setVerbose(2)
. (I presume you will have some way in the user interface to set this flag). Then let them examine the log to see if they can determine the issue, and likewise the log can be sent to developers.
Future work
-
Send this information to log files instead of the console.
-
Store the previous message in a string so a GUI can pick it up