返回 Skill 列表
extension
分类: 开发与工程无需 API Key

dojo-debug

在调试和故障排除dojo.js应用程序时使用。触发条件:dojo错误,torii连接,实体未找到,类型不匹配,debug dojo,故障排除,订阅错误,同步问题

person作者: jakexiaohubgithub

Dojo.js Debugging & Troubleshooting

When to Use

Use this skill when:

  • Debugging connection issues
  • Troubleshooting entity sync problems
  • Fixing type mismatches
  • Diagnosing subscription errors

Connection Issues

Torii Not Responding

# Check if Torii is running
curl http://localhost:8080/health

# Check Torii logs
katana & torii --world 0x... --rpc http://localhost:5050

Common causes:

  • Torii not started
  • Wrong toriiUrl in config
  • CORS blocking requests
  • World address mismatch

CORS Errors

Access to fetch blocked by CORS policy

Solution: Start Torii with CORS enabled:

torii --world 0x... --allowed-origins "*"

WebSocket Connection Failed

// Check if WebSocket is supported
if (typeof WebSocket === 'undefined') {
    console.error("WebSocket not available");
}

// Try gRPC instead
import { initGrpc } from "@dojoengine/sdk";
const grpcClient = await initGrpc({ toriiUrl, worldAddress });

Entity Issues

Entity Not Found

// Debug: Check if entity exists
const { useDojoStore } = useDojoSDK();
const allEntities = useDojoStore.getState().entities;
console.log("All entities:", Object.keys(allEntities));

// Verify entity ID format
import { getEntityIdFromKeys } from "@dojoengine/utils";
const entityId = getEntityIdFromKeys([BigInt(key1), BigInt(key2)]);
console.log("Expected entityId:", entityId);

Common causes:

  • Wrong entity key(s)
  • Entity not yet indexed by Torii
  • Query filter too restrictive

Entity Not Updating

// Check subscription is active
const [data, subscription] = await sdk.subscribeEntityQuery({...});
console.log("Subscription active:", subscription);

// Verify callback is being called
callback: ({ data, error }) => {
    console.log("Callback triggered:", { data, error });
}

Common causes:

  • Subscription filter doesn't match entity
  • Callback throwing error
  • Store not being updated

Type Issues

Schema Type Mismatch

Type 'X' is not assignable to type 'Y'

Solution: Regenerate types from ABI:

npx @dojoengine/core compile-abi path/to/manifest.json

Model Name Format

// Wrong
useModel(entityId, "Player");       // Missing namespace
useModel(entityId, "game_Player");  // Wrong separator

// Correct
useModel(entityId, "game-Player");  // namespace-ModelName

Subscription Errors

Subscription Callback Error

// Wrap callback in try-catch
callback: ({ data, error }) => {
    try {
        if (error) {
            console.error("Subscription error:", error);
            return;
        }
        processData(data);
    } catch (e) {
        console.error("Callback error:", e);
    }
}

Memory Leaks

// Always cleanup subscriptions
useEffect(() => {
    let subscription;

    async function setup() {
        [, subscription] = await sdk.subscribeEntityQuery({...});
    }
    setup();

    return () => {
        if (subscription) {
            subscription.cancel();
        }
    };
}, []);

Transaction Errors

Insufficient Funds

Transaction reverted: insufficient balance

Solution: Fund the account:

// Check balance
const balance = await provider.provider.getBalance(account.address);
console.log("Balance:", balance);

Nonce Mismatch

Invalid transaction nonce

Solution: Wait for pending transactions:

await account.waitForTransaction(tx.transaction_hash);

Contract Not Found

Contract not found in manifest

Solution: Verify contract name and namespace:

console.log("Manifest contracts:", manifest.contracts.map(c => c.tag));

Performance Issues

Slow Queries

// Use pagination
const query = new ToriiQueryBuilder()
    .withLimit(50)  // Smaller batches
    .addEntityModel("game-Player")  // Specific models only
    .build();

// Consider gRPC for better performance
import { initGrpc } from "@dojoengine/sdk";

Too Many Re-renders

// Use selectors to minimize updates
const score = useDojoStore(
    state => state.entities[entityId]?.models?.game?.Player?.score,
    (a, b) => a === b  // Custom equality
);

// Use memo for expensive computations
const sortedPlayers = useMemo(() =>
    Object.values(entities).sort((a, b) => b.score - a.score),
    [entities]
);

Debugging Tools

Log All Store Changes

useDojoStore.subscribe((state, prevState) => {
    console.log("Store changed:", {
        added: Object.keys(state.entities).filter(k => !prevState.entities[k]),
        removed: Object.keys(prevState.entities).filter(k => !state.entities[k])
    });
});

Query Torii Directly

# Check indexed entities
curl "http://localhost:8080/entities?model=game-Player&limit=10"

# Check events
curl "http://localhost:8080/events?limit=10"

Enable SDK Logging

const provider = new DojoProvider(manifest, rpcUrl, "debug");

Common Error Messages

| Error | Cause | Solution | |-------|-------|----------| | DojoProvider can only be used once | Duplicate provider | Remove duplicate | | Either client or grpcClient must be provided | SDK init failed | Check init options | | Contract did not return expected uuid | Wrong world address | Verify world address | | Failed to fetch uuid | RPC connection failed | Check RPC URL |

Quick Diagnostics

// Add to your app for debugging
function DebugPanel() {
    const { sdk, config, useDojoStore } = useDojoSDK();
    const entityCount = useDojoStore(s => Object.keys(s.entities).length);

    return (
        <div style={{ position: 'fixed', bottom: 0, right: 0, background: '#000', color: '#0f0', padding: 10 }}>
            <div>Torii: {config.toriiUrl}</div>
            <div>World: {config.manifest?.world?.address?.slice(0, 10)}...</div>
            <div>Entities: {entityCount}</div>
        </div>
    );
}