Errors in GDScript

In GDScript, error handling is typically done using exceptions, which is different from Go’s approach. However, we can simulate a similar pattern using custom classes and return values. Here’s how we might approach this:

extends Node

class_name ErrorExample

# Custom Error class to simulate Go's error type
class CustomError:
    var message: String
    
    func _init(msg: String):
        message = msg
    
    func _to_string() -> String:
        return message

# Predefined errors (similar to sentinel errors in Go)
var ErrOutOfTea = CustomError.new("no more tea available")
var ErrPower = CustomError.new("can't boil water")

# Function that may return an error
func f(arg: int) -> Array:
    if arg == 42:
        return [-1, CustomError.new("can't work with 42")]
    return [arg + 3, null]

# Function demonstrating error wrapping
func make_tea(arg: int) -> CustomError:
    if arg == 2:
        return ErrOutOfTea
    elif arg == 4:
        return CustomError.new("making tea: " + ErrPower.message)
    return null

func _ready():
    for i in [7, 42]:
        var result = f(i)
        if result[1] != null:
            print("f failed: ", result[1])
        else:
            print("f worked: ", result[0])
    
    for i in range(5):
        var err = make_tea(i)
        if err != null:
            if err.message == ErrOutOfTea.message:
                print("We should buy new tea!")
            elif "can't boil water" in err.message:
                print("Now it is dark.")
            else:
                print("unknown error: ", err)
            continue
        print("Tea is ready!")

In this GDScript version:

  1. We create a CustomError class to simulate Go’s error type.

  2. Instead of using multiple return values, we return an array where the last element is the error (if any).

  3. We use predefined CustomError instances to simulate sentinel errors.

  4. The f function demonstrates returning both a value and an error.

  5. The make_tea function shows how to return different errors based on conditions.

  6. In the _ready function (which is similar to main in Go), we demonstrate how to check for errors and handle them.

  7. We simulate error wrapping by including the message of one error in another.

  8. Instead of errors.Is, we compare error messages directly. GDScript doesn’t have a built-in way to check for error types in a chain, so this is a simplified approach.

This code maintains the spirit of Go’s error handling while adapting to GDScript’s features and idioms. Note that in real Godot projects, you might use built-in error handling mechanisms or signals for more complex scenarios.