Ruby Error - but where? - aargh!!
Posted: Sat Mar 16, 2013 2:03 am
Yes, I'm sure any of us that have played with Ruby have been there - got that new Ruby command sussed out, type in the code, and then in the little box at the bottom of the editor...
"ErrorMessage: Your code is rubbish, you can't expect me to do that!"
Dammit - but where the hell is that bug? There are dozens of lines of code to check, and my 'event' method is calling my 'doCoolStuff' method, which does a redraw of the 'draw' method - how the hell am I supposed to find it ??!?!?!
Often the message will tell you a method name where the error happened - but it doesn't often help because it is just the place where you called something - many times it's the code you're calling at the other end that's the problem. And there's not even a line number so you know where to start looking!
Well, here's a sneaky trick that you can use to get Ruby to be a little more helpful - just three extra lines of code to pop onto the end of a "def....end" block here and there...
Note the three lines of code just before 'end' (they have to go right there at the end).
Now, if there is an error in the method, you'll get the usual cryptic error message - but also a handy little printout of the backtrace.
"Backtrace" - what's that?
The backtrace is a list of all the method calls that Ruby made up to the point of there being an error, and looks something like this...
["(eval):3:in myMethod", "(eval):13:in event"]
So what does that mean?
Each little string in the list is one of the steps that Ruby took - beginning with the one closest to where the error happened. And each has the same format...
(eval) - ignore this bit - it just means that Ruby evaluated some new code.
Number - a line number in the code - actually it's one line after the one you're looking for.
in <name> - the name of the method that Ruby was running.
By following the chain of line numbers, you can follow the path taken by whatever value it was that caused the problem, checking each line number in turn for mistakes, or to find out which variable it was that had the wrong value.
Because of the way that Ruby handles errors, you don't even need this code in every single method. In most cases, our variable values start their life either from the 'event' method reading inputs, reDraws firing a 'draw' method, or mouse moves - so you only really need the extra code at the end of those methods. However, you can't get a backtrace if your Ruby is just "bare code", only if you are using method definitions ("def...end").
Here's an example showing what I mean - try typing zero into the integer input box...
You will see from the 'backtrace' just how Ruby keeps a record of each step - where the divide caused an error, the line where the 'divide' method was called, and where the 'test' method was called by 'event' - each with a line number (+1) of where each call was made. Following that chain backwards, we end up at the "test(@in)" statement, and can reason that @in must be the variable with the rogue zero.
Juts be careful to type that code accurately - a mistake in those three lines could make the error reporting even more confusing, or even stop you from getting error messages at all!!
"ErrorMessage: Your code is rubbish, you can't expect me to do that!"
Dammit - but where the hell is that bug? There are dozens of lines of code to check, and my 'event' method is calling my 'doCoolStuff' method, which does a redraw of the 'draw' method - how the hell am I supposed to find it ??!?!?!
Often the message will tell you a method name where the error happened - but it doesn't often help because it is just the place where you called something - many times it's the code you're calling at the other end that's the problem. And there's not even a line number so you know where to start looking!
Well, here's a sneaky trick that you can use to get Ruby to be a little more helpful - just three extra lines of code to pop onto the end of a "def....end" block here and there...
- Code: Select all
def myMethod
# Extra Cool funky code
# goes here
rescue => error
watch "Error help",error.backtrace
raise error
end
Note the three lines of code just before 'end' (they have to go right there at the end).
Now, if there is an error in the method, you'll get the usual cryptic error message - but also a handy little printout of the backtrace.
"Backtrace" - what's that?
The backtrace is a list of all the method calls that Ruby made up to the point of there being an error, and looks something like this...
["(eval):3:in myMethod", "(eval):13:in event"]
So what does that mean?
Each little string in the list is one of the steps that Ruby took - beginning with the one closest to where the error happened. And each has the same format...
(eval) - ignore this bit - it just means that Ruby evaluated some new code.
Number - a line number in the code - actually it's one line after the one you're looking for.
in <name> - the name of the method that Ruby was running.
By following the chain of line numbers, you can follow the path taken by whatever value it was that caused the problem, checking each line number in turn for mistakes, or to find out which variable it was that had the wrong value.
Because of the way that Ruby handles errors, you don't even need this code in every single method. In most cases, our variable values start their life either from the 'event' method reading inputs, reDraws firing a 'draw' method, or mouse moves - so you only really need the extra code at the end of those methods. However, you can't get a backtrace if your Ruby is just "bare code", only if you are using method definitions ("def...end").
Here's an example showing what I mean - try typing zero into the integer input box...
You will see from the 'backtrace' just how Ruby keeps a record of each step - where the divide caused an error, the line where the 'divide' method was called, and where the 'test' method was called by 'event' - each with a line number (+1) of where each call was made. Following that chain backwards, we end up at the "test(@in)" statement, and can reason that @in must be the variable with the rogue zero.
Juts be careful to type that code accurately - a mistake in those three lines could make the error reporting even more confusing, or even stop you from getting error messages at all!!