Mruby: Errors in Ruby code and how to find them

by Paweł Świątkowski
06 Oct 2024

In the article about using mrbgems we had a situation when ARGV constant was not defined, but referenced. As a result the code execution failed (the side-effects were not produced), however it did that completely silently. No error message was emitted. And even the exit code was zero.

This is obviously bad. So I set to fix it. By examining mruby source code I discovered mrb_print_error function. Putting it to use looks like this:

#define MRUBY_ERROR 1

// ...

/* handle exceptions */
if(mrb->exc) {
  fputs("Error when executing Ruby code:\n", stderr);
  mrb_print_error(mrb);
  mrb_close(mrb);
  return MRUBY_ERROR;
}

We can invoke it by referencing some undefined constant in our Ruby code, for example:

p THIS_IS_UNDEFINED

Then after compilation and running we get:

Error when executing Ruby code:
(unknown):0: uninitialized constant THIS_IS_UNDEFINED (NameError)

We can also verify that the exit code was set.

$ echo $?
1

Of course, a (not so) small problem here is that the reference to original line is lost, but it’s still better than the silence. The good news, however, is that we can fix this!

When compiling Ruby code into the bytecode using mrbc program we can specify the -g flag. From the documentation it’s to “produce debugging information”. Now if we run our final executable we will get more information:

Error when executing Ruby code:
trace (most recent call last):
main.rb:42: uninitialized constant THIS_IS_UNDEFINED (NameError)

It might be interesting to see what’s the size difference in bytecode for versio with debugging information and without. For my simple script it looks as follows:

  • Ruby script: 889 bytes
  • C file with bytecode without debugging information: 6364
  • Analogous C file with debugging information: 7503

As you can see, it’s certainly not for free. The size is almost 18% larger. However at least for development phase the gain in having precise information about the source of error is huge.

end of the article

Tags: ruby mruby

This article was written by me – Paweł Świątkowski – on 06 Oct 2024. I'm on Fediverse (Ruby-flavoured account, Elixir-flavoured account). Let's talk.