Listing enum constants in error messages

Issue #1318 resolved
hahawoo
created an issue

I think it would be helpful if errors caused by invalid enum constants listed the valid constants in the error message.

So instead of:

Error

main.lua:2: Invalid draw mode: 0


Traceback

[C]: in function 'rectangle'
main.lua:2: in function 'draw'
[C]: in function 'xpcall'

it would be something like:

Error

main.lua:2: Invalid draw mode: 0

It can be: line or fill


Traceback

[C]: in function 'rectangle'
main.lua:2: in function 'draw'
[C]: in function 'xpcall'

Most enums don't have that many constants:

Scancode: 194
KeyConstant: 144
CompressedImageFormat: 36
CanvasFormat: 17
GamepadButton: 15
Event: 14
CursorType: 13
JointType: 9
JoystickHat: 9
BlendMode: 8
DistanceModel: 7
StencilAction: 6
CompareMode: 6
GamepadAxis: 6
PowerState: 5
MeshDrawMode: 4
ShapeType: 4
AreaSpreadDistribution: 4
GraphicsLimit: 4
WrapMode: 4
FileMode: 4
BodyType: 3
CompressedDataFormat: 3
JoystickInputType: 3
ParticleInsertMode: 3
SpriteBatchUsage: 3
ArcType: 3
GraphicsFeature: 3
AlignMode: 3
BufferMode: 3
LineJoin: 3
MessageBoxType: 3
FilterMode: 2
PointStyle: 2
TimeUnit: 2
SourceType: 2
LineStyle: 2
FileDecoder: 2
ImageFormat: 2
FullscreenType: 2
StackType: 2
BlendAlphaMode: 2
DrawMode: 2

(Generated by this code, if anyone is interested.)

api = require('love_api') -- https://github.com/love2d-community/love-api

enums = {}

for _, module_ in ipairs(api.modules) do
  for _, enum in ipairs(module_.enums or {}) do
    table.insert(enums, {name = enum.name, constants = #enum.constants})
  end
end

table.sort(enums, function(a, b) return a.constants > b.constants end)

for _, enum in ipairs(enums) do
  print(enum.name..': '..enum.constants)
end

Obviously functions with key/scancode arguments are exempt! :)

But even CanvaFormat (which has a lot of constants) doesn't look so bad:

listedconstants.png

(If anyone is interested in the fake error code...)

function love.load()
    love.graphics.setNewFont(14)
    love.graphics.setBackgroundColor(89/255, 157/255, 220/255)
    p = [[
Error

main.lua:2: Invalid canvas format: asdf

It can be: normal, hdr, rgba8, rgba4, rgba5a1, rgb565, rgb10a2, rgba16f, rgba32f, rg11b10f, srgb, r8, rg8, r16f, rg16f, r32f or rg32f


Traceback

[C]: in function rectangle
main.lua:2: in function draw
[C]: in function xpcall

Press Ctrl+C or tap to copy this error
]]

    screenshot = true
end

function love.draw()
    local pos = 70
    love.graphics.printf(p, pos, pos, love.graphics.getWidth() - pos)
    if screenshot then
        love.graphics.captureScreenshot('fakeerror_'..os.time()..'.png')
        screenshot = false
    end
end

Comments (5)

  1. Raidho

    The error screen is there to provide debug information and it does, to all necessary extent. I don't think it should also duplicate the user manual.

  2. hahawoo reporter

    Actually what this issue (and #1317) should have been is: showing given and expected values in all messages for errors due to invalid arguments (unless it's a key/scancode argument or something else that makes it tricky).

  3. Bart van Strien
    • changed status to open

    I feel like this could be a worthwhile addition. That said, I'm afraid it's probably going to take a while, since it needs a proper solution, rather than us manually adding all these values to the error messages. It's not impossible, it just takes some dedication.

  4. Bart van Strien

    Show (short) list of possible enum values when an invalid value is encountered (resolves #1318)

    All enum errors have (hopefully) been changed to a luax_enumerror, which has a fixed error message. If additionally a list of valid options is passed, it lists that in the error message. For every enum error with few options I've implemented this using a getConstants call.

    This solution has been designed specifically to reduce the number of template instantiations (as I've been told that was a concern). All new template code happens in places where there already was an instantiation of the relevant StringMap. Of course there is still std::vector<std::string>...

    → <<cset 33eaf4a32a69>>

  5. Log in to comment