Page 1 of 1

Catcher - better errorhandler implementation and debugging utilities

Posted: Thu Jul 28, 2022 10:58 am
by unknownuser
Catcher (tried to keep in line with LOVE library naming conventions :ultrahappy:) is a currently small library that primarily implements a replacement for love.errorhandler, since I find it a bit lacking (I think it's been neglected in general). The default function displays the error message and traceback, but I always found debug.traceback's results a little hard to read, due to all the irrelevant information.

This replacement limits the shown stack frames to only relevant information (this is actually slightly variable, since you can pass in an offset to the builder function), from the error/assert call up to just below love.run (this might cause issues if you're testing a love.run implementation). Additionally, Catcher lets you move up and down the stack to inspect a frame's locals, there was a lot of pain involved in getting parameters ordered correctly, especially taking varargs into account.

The formatting isn't perfect, notably if a frame is too long (wraps), the cursor column won't align with it anymore, but line wrapping works fine with error messages and locals. You can also pass the builder function a custom_fmt table to change certain aspects of the result, in the attached screenshot, clear_color is set to black.
It tries to be similar to the default function controls-wise, retaining ctrl-c to copy and escape to exit, but also provides the stack cursor and ctrl-t to start the console debugger (can also be swapped out for a custom function).

Capture.png
Capture.png (38 KiB) Viewed 3898 times
Here's an example usage, with the default arguments:

Code: Select all

love.errorhandler = require("catcher").errorhandler({
	frame = " %name:%currentline @ (%short_src:%linedefined)\n",
	lclvar = "\t%name = %value\n",
	clear_color = {89/255, 157/255, 220/255},
	text_color = {1, 1, 1},
	text_size = 14,
	inset = 70
}, debug.debug, 0, nil)
Eventually I want to a add profiler using jit.profile (especially since I couldn't find any existing ones), but that's something for another day right now.

Re: Catcher - better errorhandler implementation and debugging utilities

Posted: Thu Jul 28, 2022 5:41 pm
by ReFreezed
Nice. A small improvement over the standard error handler. I feel like the format parameters should be custom for the library though, like frame="%name:%line @ (%file:%linedefined)" instead of frame="%s:%d @ (%s:%d)" so you can reorder the values, like frame="%file:%line (%name)".

Feature suggestions: Show a preview/snippet of the relevant code from the source file for the selected stack frame (if available). Pressing a key to launch a text editor at the file and line for the selected stack frame.

Btw, the example has an error. love.errorhandling should be love.errorhandler.

Re: Catcher - better errorhandler implementation and debugging utilities

Posted: Thu Jul 28, 2022 6:30 pm
by unknownuser
Btw, the example has an error. love.errorhandling should be love.errorhandler.
Fixed.
I feel like the format parameters should be custom for the library though
I agree, it came to mind at one point but the effort to get string interpolation working made me put it to the side. Getting formatting working nicely is exhausting to me.

The feature suggestions are interesting, the source preview I could probably do, but I'm not sure how file associations work on Windows and OSX and if I'd need FFI, on Linux I imagine an xdg-open call would be fine.

Re: Catcher - better errorhandler implementation and debugging utilities

Posted: Thu Jul 28, 2022 10:01 pm
by ReFreezed
For the formatting you could just change this:

Code: Select all

frame.str = fmt.frame:format(
	frame.name or "anonymous", frame.currentline,
	frame.short_src, frame.linedefined)

-- to something like this:
frame.str = fmt.frame:gsub("%%(%w+)", {
	name        = frame.name or "anonymous",
	file        = frame.short_src,
	line        = frame.currentline,
	linedefined = frame.linedefined
})
To launch programs, using os.execute() is fine. Let the user specify the path to the program - no need to care about file associations (i.e. don't launch the files themselves).

Code: Select all

os.execute(pathToProgram.." "..filePath..":"..lineNumber) -- Simplified. You should put quotes around paths with spaces and whatnot.
Most competent text editors support opening files at a certain line number like this.

Re: Catcher - better errorhandler implementation and debugging utilities

Posted: Mon Aug 01, 2022 4:43 am
by unknownuser

Code: Select all

fmt.frame:gsub("%%(%w+)", {...})
That's a very nice interpolation hack.

I've updated the attachment with some changes: better formatting options, and a change to how locals are collected is the most of it, the latter change cleaned up a lot of indexing spaghetti, so that's good. Other than that it's just a few small bugfixes. I'm not convinced of the text editor feature, since I couldn't get codium to accept path:line as an argument and I'm not eager to encode a massive table of editors and their switches to open a file at a line. On the upside, vscode supports opening path:line formatted links from the integrated terminal.

Re: Catcher - better errorhandler implementation and debugging utilities

Posted: Mon Aug 01, 2022 8:25 pm
by ReFreezed
Just like you don't need to care about file associations, the text editor command could be a user-provided format too, like editor="path/to/sublime_text.exe %file:%line". Also, I'd consider it an important feature. I mean, how often do you want to know the error and stack information, but not want to go to the relevant code and fix the problem. It's just another small tool that'll make the debugging process a bit smoother.