One thing I always do with non-quick-script programs I write (even with some), I add in my own debugging, showing the steps and a concise (not necessarily detailed) message telling me what it was trying to do when it failed, or why it failed (in the case I have something like a try-catch block).
Here's an example of what I mean (in pseudocode):
Code:
string program = "foo"
function write-to-stream(stream, message):
string func = "write-to-stream"
try:
print $stream, $message
catch (ioexception ioex):
print [STDOUT|STDERR] "$program:$func:Failed to write $message to $stream"
write-to-stream(STDOUT, "hello, world")
Of course, it would be too time-consuming for you too go back and add something like this in now, but this is more or less just a guideline I follow as when I learned to program, it was without mechanisms like try-catch blocks (think QBASIC/QuickBASIC and C) and an method I implemented when I watched my classmates struggle to find the crippling bug in their code.