Debug Logging
This guide covers debugging techniques for Multiforum development.
Frontend Debugging
Browser DevTools
Console Logging
// Basic logging
console.log("Value:", someValue);
// Structured logging
console.log("User data:", { user, permissions, channel });
// Grouping related logs
console.group("Permission Check");
console.log("User:", username);
console.log("Permission:", permissionKey);
console.log("Result:", hasPermission);
console.groupEnd();
Apollo DevTools
Install the Apollo Client DevTools browser extension:
- View cache contents
- Inspect queries/mutations
- Monitor network activity
- Debug cache policies
Vue DevTools
Install Vue DevTools:
- Inspect component hierarchy
- View props and state
- Debug Pinia stores
- Track events
Network Debugging
GraphQL Requests
- Open DevTools → Network tab
- Filter by "graphql"
- Click a request to see:
- Request payload (query + variables)
- Response data
- Timing information
Common Issues
| Symptom | Likely Cause |
|---|---|
| 401 errors | Token expired or invalid |
| 403 errors | Missing permissions |
| Network errors | Backend not running |
| Slow queries | Missing database indexes |
Logging Composable State
// In a composable
export function useMyComposable() {
const state = ref(null);
watchEffect(() => {
console.log("[useMyComposable] State changed:", state.value);
});
return { state };
}
Component Lifecycle Debugging
<script setup lang="ts">
import { onMounted, onUpdated, onUnmounted } from "vue";
onMounted(() => {
console.log("[MyComponent] Mounted");
});
onUpdated(() => {
console.log("[MyComponent] Updated");
});
onUnmounted(() => {
console.log("[MyComponent] Unmounted");
});
</script>
Backend Debugging
Console Logging
// In resolvers
export const createDiscussion = async (root, args, context) => {
console.log("[createDiscussion] Input:", args.input);
try {
const result = await ogm.model("Discussion").create(args.input);
console.log("[createDiscussion] Created:", result.id);
return result;
} catch (error) {
console.error("[createDiscussion] Error:", error);
throw error;
}
};
Permission Debugging
// In permission rules
export const canCreateDiscussion = rule()(async (parent, args, context) => {
console.log("[canCreateDiscussion] Checking...");
console.log(" User:", context.user?.username);
console.log(" Channel:", args.channelUniqueName);
const hasPermission = await checkPermission(context, "canCreateDiscussion");
console.log(" Result:", hasPermission);
return hasPermission;
});
Database Query Debugging
// Log Cypher queries
const session = driver.session();
const query = `
MATCH (d:Discussion {id: $id})
RETURN d
`;
console.log("[DB Query]", query);
console.log("[DB Params]", { id: discussionId });
const result = await session.run(query, { id: discussionId });
console.log("[DB Result]", result.records.length, "records");
Slack Webhook Logging
If configured, mutations are logged to Slack:
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
Useful for monitoring production activity.
Test Debugging
Vitest Debugging
describe("MyFunction", () => {
it("should work", () => {
const input = { foo: "bar" };
console.log("Input:", input);
const result = myFunction(input);
console.log("Result:", result);
expect(result).toBeDefined();
});
});
Run with verbose output:
npm run test:unit -- --reporter=verbose
Playwright Debugging
test("user flow", async ({ page }) => {
// Pause for manual inspection
await page.pause();
// Take screenshot
await page.screenshot({ path: "debug.png" });
// Log page content
console.log(await page.content());
});
Run in headed mode:
npx playwright test --headed
Run with debug mode:
npx playwright test --debug
Common Debugging Scenarios
Authentication Issues
- Check token in localStorage
- Verify token isn't expired
- Check auth hint cookies
- Look for UNAUTHENTICATED errors in console
// Debug auth state
console.log("Token:", localStorage.getItem("access_token"));
console.log("Auth hint:", document.cookie);
Permission Issues
- Check user's role assignments
- Verify channel permissions
- Check suspension status
- Review permission resolution logic
// Debug permissions
const permissions = getAllPermissions(user, channel);
console.log("Resolved permissions:", permissions);
Cache Issues
- Check Apollo cache in DevTools
- Verify cache updates after mutations
- Consider cache eviction
// Force refetch
const { refetch } = useQuery(MY_QUERY);
await refetch();
SSR Issues
- Check if code runs on server vs client
- Verify cookies are accessible
- Look for hydration mismatches
if (process.client) {
console.log("[Client] Running on client");
} else {
console.log("[Server] Running on server");
}
Performance Debugging
Frontend
// Measure execution time
console.time("expensive-operation");
await expensiveOperation();
console.timeEnd("expensive-operation");
Backend
// Log query timing
const start = Date.now();
const result = await session.run(query, params);
console.log(`Query took ${Date.now() - start}ms`);
Error Tracking
Sentry Integration
If configured, errors are tracked in Sentry:
VITE_SENTRY_DSN=https://...@sentry.io/...
Errors include:
- Stack traces
- User context
- Environment info
Best Practices
Structured Logging
const log = {
info: (msg: string, data?: object) =>
console.log(`[INFO] ${msg}`, data || ""),
warn: (msg: string, data?: object) =>
console.warn(`[WARN] ${msg}`, data || ""),
error: (msg: string, error?: Error) =>
console.error(`[ERROR] ${msg}`, error || ""),
};
log.info("Creating discussion", { title, channelId });
Remove Debug Logs
Before committing:
- Remove
console.logstatements - Use conditional logging for development only
- Consider a proper logging library for production
if (import.meta.env.DEV) {
console.log("Debug info:", data);
}