Weird behavior with GDScript classes named `Error`

Godot Version

v4.2.2.stable.flathub [15073afe3]

Question

Hello, I am moving this post from Reddit because I do not have enough karma to post on r/godot. Everything below is copied and pasted from Reddit, sorry for the trouble


Hello, this is my first post so sorry if it is somewhat ignorant…

I am working on a game with Godot and GDScript. There is a part of my code where I want error handling, because it has a lot of logic and validation, since GDScript doesn’t have a native exception type I decided to use a trick I first learned from Golang. I wrote my code like this:

class Error:
    var message: String

    func _init(message: String):
        self.message = message

static func div(a: int, b: int):
    if b == 0:
        return Error.new("divide by 0")
    return a / b

static func approx_area(radius: int):
    var approx_pi = div(339, 108)
    if approx_pi is Error:
        return approx_pi
    return approx_pi * radius * radius

You can see how it is similar to the equivalent Go code:

func ApproxArea(radius int) (int, error) {
    approxPi, err := div(339, 108)
    if err != nil {
        return 0, err
    }
    return approxPi * radius * radius, nil
}

But I noticed something weird. When I name a class Error, I can subclass it like normal but when I use is to check inheritance, then it behaves differently. I checked to make sure there are no built in classes called Error, I can’t think of any reason why it would conflict…

class Error:
    pass
class NoSaveError extends Error:
    pass

class Exception:
    pass
class NoSaveException extends Exception:
    pass

static func test():
    var err = NoSaveError.new()
    print("Is sub?:   ", err is NoSaveError)
    print("Is super?: ", err is Error)
    
    var ex = NoSaveException.new()
    print("Is sub?:   ", ex is NoSaveException)
    print("Is super?: ", ex is Exception)

prints

Is sub?:   true
Is super?: false
Is sub?:   true
Is super?: true

I’m sorry if I’m just missing something very obvious here! I really love Godot, it is just this one little thing that is confusing to me… hopefully some of you know :3

1 Like

There is no class, but there is an enum named Error. This might be the issue here.

I did not work with subclasses before, but you could try to give the whole class a class_name, e.g. SomeClass and see if you can test err is SomeClass.Error

1 Like

That’s it~ in the is comparison, it was referring to the global enum Error… I wonder why the Error defined in the local scope doesn’t override it. But I guess GDScript scoping behavior is different from most other programming languages…

I was looking into the GDScript VM source code, I guess it never occurred to me that they would need to have different versions of the type test operator depending on what type you are checking (godot/modules/gdscript/gdscript_byte_codegen.cpp at master · godotengine/godot · GitHub) I guess it makes sense, though.

I wonder what the advantage of having a type test for an enum is, since the underlying type of an enum is an int (so 0 is Error returns true) but I guess it is not harmful… it lines up with Godot’s philosophy of do not throw an error if it can be avoided, because games are not business critical applications

Thank you for all the help! I have decided to go forward and just use the name Exception in my code, I think it is clearer anyway. Even then, I learned something more about programming today… Take care, it was very nice talking to you!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.