Troubleshooting
Common errors and solutions for tsunagiya.
Test Times Out
Symptom
Test fails with Deno.test default timeout (5 seconds).
Causes and Solutions
1. Forgot to call pool.uninstall()
→ Always wrap in try/finally.
2. WebSocket onclose never fires
Promise never resolves, so the test never completes.
→ Call ws.close() after receiving EOSE.
3. Latency setting is too large
→ Use small values in tests. Use latency: 0 (default) for all but latency-specific tests.
4. streamEvents keeps running
→ Specify count or call handle.stop() at test end.
5. Extend Deno test timeout
Deno.test({
name: "slow test",
fn: async () => {/* ... */},
sanitizeOps: false,
sanitizeResources: false,
});Events Not Received
Symptom
Sending REQ returns no events.
Causes and Solutions
1. Forgot to call relay.store()
→ Register test data using store().
2. Filter doesn't match
→ Verify that the kind of stored events matches the kinds in the filter.
3. Created WebSocket before calling pool.install()
→ Call pool.install() before creating WebSocket connections.
4. onREQ handler returns an empty array
→ Setting an onREQ handler skips auto-matching. Return events from the handler or use store() without onREQ.
WebSocket Connection Fails
Symptom
onerror → onclose(code: 1006) fires on connection.
Causes and Solutions
1. URL not registered
→ Register the target URL with pool.relay().
2. refuse() was called
→ Check whether the connection was before refuse() was called. Use reset() to reset.
3. connectionTimeout is too short
→ Set the timeout to an appropriate value.
"MockPool is already installed" Error
Symptom
Error: MockPool is already installedCause
pool.install() was called twice.
"MockPool is not installed" Error
Symptom
Error: MockPool is not installedCause
pool.uninstall() was called before install, or called twice.
"WebSocket is not open" Error
Symptom
DOMException: WebSocket is not openCause
send() was called when readyState is not OPEN.
Debugging
Code Examples
Timeout cause: forgetting to call uninstall:
// ❌ forgetting uninstall breaks the next test
pool.install();
// test...
// pool.uninstall() is missing!
// ✅ always wrap in try/finally
pool.install();
try {
// test
} finally {
pool.uninstall();
}Forgetting to call WebSocket close():
// ❌ not calling close() after EOSE
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg[0] === "EOSE") {
// forgot ws.close()
}
};
// ✅ call close() after receiving EOSE
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg[0] === "EOSE") {
ws.close();
}
};Creating WebSocket before install:
// ❌ real WebSocket will be used
const ws = new WebSocket("wss://relay.example.com");
pool.install(); // install is too late
// ✅ create WebSocket after install
pool.install();
const ws = new WebSocket("wss://relay.example.com");"MockPool is already installed" error:
// ❌ double install
pool.install();
pool.install(); // Error!
// ✅ check with installed property
if (!pool.installed) {
pool.install();
}"MockPool is not installed" error:
// ✅ check with installed property
if (pool.installed) {
pool.uninstall();
}"WebSocket is not open" error:
// ✅ send in onopen
ws.onopen = () => {
ws.send(JSON.stringify(["REQ", "s", { kinds: [1] }]));
};
// ❌ send immediately (still in CONNECTING state)
const ws = new WebSocket("wss://relay.example.com");
ws.send(JSON.stringify(["REQ", "s", { kinds: [1] }])); // Error!Debugging: enable logging:
pool.relay("wss://relay.example.com", { logging: true });Custom log handler:
const logs: LogEntry[] = [];
pool.relay("wss://relay.example.com", {
logging: (entry) => {
logs.push(entry);
console.log(JSON.stringify(entry, null, 2));
},
});Inspect with the received property:
// inspect after test
console.log("Received messages:", JSON.stringify(relay.received, null, 2));
console.log("REQ count:", relay.countREQs());
console.log("EVENT count:", relay.countEvents());Inspect with the connections property:
console.log("Active connections:", pool.connections);Related Documentation
- FAQ — Frequently asked questions
- API Reference — Correct API usage
- Tutorial — Basic usage