?? Debugging Tutorial

Learn how to find and fix bugs using Babalawo and debugging tools.

Static Analysis with Babalawo

Catch errors before running your code:

# Run Babalawo linter
ifa check main.ifa

# Example output:
# main.ifa:15:5 WARNING: Unused variable 'temp'
#   ? Ogbè wisdom: "A journey begins with a single step."
#
# main.ifa:23:10 ERROR: Undefined variable 'result'
#   ? Check your variable declarations.

Print Debugging

Use Irosu for debug output:

ise process_data(data) {
    Irosu.fo("[DEBUG] Input: " + Ogbe.format_json(data));
    
    ayanmo result = transform(data);
    Irosu.fo("[DEBUG] After transform: " + Ogbe.format_json(result));
    
    // Use kigbe for errors (writes to stderr)
    ti (result == nil) {
        Irosu.kigbe("[ERROR] Transform returned nil!");
    }
    
    padap? result;
}

Tracing Execution

Track function calls and timing:

ise trace(name, func) {
    ayanmo start = Iwori.now_ms();
    Irosu.fo("[TRACE] ? Entering " + name);
    
    ayanmo result = func();
    
    ayanmo elapsed = Iwori.now_ms() - start;
    Irosu.fo("[TRACE] ? Exiting " + name + " (" + elapsed + "ms)");
    
    padap? result;
}

// Usage
ayanmo result = trace("processOrder", || {
    ayanmo order = fetch_order(id);
    ayanmo validated = trace("validateOrder", || validate(order));
    padap? trace("saveOrder", || save(validated));
});

Error Context

Wrap errors with context:

ise fetch_user(id) {
    ayanmo result = Okanran.try(|| {
        ayanmo response = Otura.get("/api/users/" + id);
        ti (response["status"] != 200) {
            padap? Okanran.error("HTTP " + response["status"]);
        }
        padap? Ogbe.parse_json(response["body"]);
    });
    
    // Add context to error
    ti (Okanran.is_error(result)) {
        padap? Okanran.error("Failed to fetch user " + id + ": " + Okanran.message(result));
    }
    
    padap? result;
}

Debugging Common Issues

Undefined Variable

// Problem:
ayanmo x = 10;
Irosu.fo(y);  // ERROR: Undefined variable 'y'

// Fix: Check spelling, ensure variable is declared before use
ayanmo x = 10;
Irosu.fo(x);  // ?

Type Mismatch

// Problem:
ayanmo count = "5";
ayanmo total = count + 10;  // "510" (string concat, not addition!)

// Fix: Use Ogbe for type conversion
ayanmo count = Ogbe.parse_int("5");
ayanmo total = count + 10;  // 15 ?

Off-by-One Errors

// Problem:
ayanmo items = [1, 2, 3];
fun i ninu [0, 1, 2, 3] {  // Index 3 doesn't exist!
    Irosu.fo(Ogunda.get(items, i));
}

// Fix: Use proper bounds
fun i ninu Obara.range(0, Ogunda.len(items)) {
    Irosu.fo(Ogunda.get(items, i));
}

REPL for Interactive Debugging

# Start REPL
ifa repl

# Test expressions interactively
>>> ayanmo data = [1, 2, 3, 4, 5]
>>> Ogunda.filter(data, |x| x > 3)
[4, 5]
>>> Osa.sum(data)
15

Babalawo Diagnostic Levels

// Severity levels:
// - Error: Code will not run correctly
// - Warning: Potential issue, code may work
// - Info: Suggestion for improvement
// - Hint: Style recommendation

# Run with all levels
ifa check --verbose main.ifa

# Suppress warnings
ifa check --no-warnings main.ifa