Troubleshooting & Patterns

Solutions to Common Issues & Battle-Tested Patterns

Find quick fixes for common problems and learn proven patterns for building robust Hype applications.

๐Ÿ”

๐Ÿšจ Quick Fixes

โšก Most Common Issues
macOS Gatekeeper
xattr -d com.apple.quarantine ./hype
Module not found
local http = require('http')
Database locked
db:close() -- Close when done
Port in use
server:listen(8081) -- Try different port

๐Ÿ”ง Troubleshooting

๐Ÿ“ฆ hype: command not found
โ–ผ
Symptom: After installation, `hype` command is not recognized
Solutions:
# 1. Check if hype is in PATH
which hype

# 2. Add to PATH manually
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# 3. Use full path
~/.local/bin/hype version

# 4. Reinstall
curl -sSL https://raw.githubusercontent.com/twilson63/hype/main/install.sh | bash
๐Ÿ”จ Module not found in multi-file project
โ–ผ
Symptom: Build fails with "module not found" error
Solution:
-- Use relative paths with ./
local utils = require('./utils')      -- โœ“ Correct
local helpers = require('./lib/helpers') -- โœ“ Correct

-- NOT:
local utils = require('utils')        -- โœ— Wrong
local utils = require('/abs/path')    -- โœ— Avoid absolute paths

Project structure example:

project/
โ”œโ”€โ”€ main.lua
โ”œโ”€โ”€ utils.lua
โ””โ”€โ”€ lib/
    โ””โ”€โ”€ helpers.lua
โŒ attempt to index a nil value
โ–ผ
Symptom: Error: attempt to index global 'http' (a nil value)
Common causes and fixes:
-- 1. Module not loaded
local http = require('http')  -- Add this!

-- 2. Missing error checking
local resp, err = http.get(url)
if err then
    print("Error:", err)
    return
end
print(resp.body)  -- Safe now

-- 3. Chain method on nil
app:SetRoot(text, true):Run():Stop()  -- Wrong: Run() returns nil

-- Fix:
app:SetRoot(text, true)
app:Run()
๐ŸŽ macOS Gatekeeper blocks executable
โ–ผ
Symptom: "cannot be opened because it is from an unidentified developer"
Solutions:
# Remove quarantine attribute
xattr -d com.apple.quarantine ./hype

# For built apps
xattr -c ./myapp

# Alternative: Sign the binary
codesign -s - ./myapp
๐ŸŒ HTTP connection refused
โ–ผ
Symptom: HTTP requests fail with "connection refused"
Solutions:
-- 1. Ensure server is running
local server = http.newServer()
go(function() server:listen(8080) end)
sleep(0.1)  -- Give server time to start

-- 2. Check port availability (in terminal)
lsof -i :8080     # macOS/Linux
netstat -an | findstr 8080  # Windows

-- 3. Use different port
server:listen(8081)  -- Try alternative port
๐Ÿ—„๏ธ Database is locked
โ–ผ
Symptom: BoltDB returns "database is locked" error
Solution:
-- Use single database connection
local db_instance = nil

function get_db()
    if not db_instance then
        db_instance = kv.open("./data.db")
    end
    return db_instance
end

-- Always close when done
function cleanup()
    if db_instance then
        db_instance:close()
        db_instance = nil
    end
end

-- Use transactions for consistency
db:transaction(function()
    db:put("users", "id1", "data1")
    db:put("users", "id2", "data2")
end)

๐ŸŽฏ Common Patterns

๐Ÿ–ฅ๏ธ

CLI Application

Build command-line tools with subcommands and options

local commands = {}

function commands.serve(args)
    local port = args[1] or "8080"
    -- Start server
end

-- Main
local cmd = arg[1] or "help"
local handler = commands[cmd] or commands.help
handler(arg)
๐Ÿ”„

Retry Pattern

Automatically retry failed operations with backoff

function retry(fn, options)
    local attempts = options.attempts or 3
    local delay = options.delay or 1
    
    for i = 1, attempts do
        local ok, result = pcall(fn)
        if ok then return result end
        
        if i < attempts then
            sleep(delay)
            delay = delay * 2
        end
    end
end
๐Ÿ‘ท

Worker Pool

Process tasks concurrently with controlled parallelism

function WorkerPool(size)
    local self = {workers = {}, tasks = {}}
    
    function self:addTask(fn, args)
        table.insert(self.tasks, {fn = fn, args = args})
    end
    
    function self:start()
        for i = 1, size do
            go(function() self:worker() end)
        end
    end
    
    return self
end
โšก

Circuit Breaker

Prevent cascading failures in distributed systems

function CircuitBreaker(threshold)
    local self = {
        failures = 0,
        state = "closed"
    }
    
    function self:call(fn)
        if self.state == "open" then
            return nil, "Circuit open"
        end
        
        local ok, result = pcall(fn)
        if not ok then
            self.failures = self.failures + 1
            if self.failures >= threshold then
                self.state = "open"
            end
        end
        return result
    end
    
    return self
end
๐Ÿ“Š

Rate Limiter

Control request rates with token bucket algorithm

function RateLimiter(rate, burst)
    local self = {
        tokens = burst,
        lastUpdate = os.clock()
    }
    
    function self:allow()
        local now = os.clock()
        local elapsed = now - self.lastUpdate
        self.tokens = math.min(burst, 
            self.tokens + elapsed * rate)
        
        if self.tokens >= 1 then
            self.tokens = self.tokens - 1
            return true
        end
        return false
    end
    
    return self
end
๐Ÿงช

Testing Framework

Simple but effective unit testing for Lua code

function test(name, fn)
    io.write(name .. " ... ")
    local ok, err = pcall(fn)
    if ok then
        print("โœ“")
    else
        print("โœ—")
        print("  Error:", err)
    end
end

function assertEquals(actual, expected)
    if actual ~= expected then
        error(string.format("Expected %s, got %s", 
            expected, actual))
    end
end

๐Ÿ“š Additional Resources

๐Ÿ“–

Full Guide

Complete troubleshooting guide with all patterns and solutions

View Markdown
๐ŸŽฎ

REPL Guide

Debug interactively with the TUI REPL

REPL Docs
๐Ÿ”Œ

API Reference

Complete module documentation

API Docs
๐Ÿ’ฌ

Community

Get help from the Hype community

Discussions