Skip to main content

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

  1. Open DevTools → Network tab
  2. Filter by "graphql"
  3. Click a request to see:
    • Request payload (query + variables)
    • Response data
    • Timing information

Common Issues

SymptomLikely Cause
401 errorsToken expired or invalid
403 errorsMissing permissions
Network errorsBackend not running
Slow queriesMissing 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

  1. Check token in localStorage
  2. Verify token isn't expired
  3. Check auth hint cookies
  4. Look for UNAUTHENTICATED errors in console
// Debug auth state
console.log("Token:", localStorage.getItem("access_token"));
console.log("Auth hint:", document.cookie);

Permission Issues

  1. Check user's role assignments
  2. Verify channel permissions
  3. Check suspension status
  4. Review permission resolution logic
// Debug permissions
const permissions = getAllPermissions(user, channel);
console.log("Resolved permissions:", permissions);

Cache Issues

  1. Check Apollo cache in DevTools
  2. Verify cache updates after mutations
  3. Consider cache eviction
// Force refetch
const { refetch } = useQuery(MY_QUERY);
await refetch();

SSR Issues

  1. Check if code runs on server vs client
  2. Verify cookies are accessible
  3. 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.log statements
  • Use conditional logging for development only
  • Consider a proper logging library for production
if (import.meta.env.DEV) {
console.log("Debug info:", data);
}