Troubleshooting Examples
Purpose: Code examples for common troubleshooting scenarios
Last Updated: 2024-11-28
Connection Issues
Testing Database Connection
# Check database is running
docker ps | grep postgres
# Test connection directly
psql -h localhost -p 54320 -U savvi -d savvi_studio -c "SELECT 1"
# Check connection string
echo $DATABASE_URL
Verifying Schema Loaded
# List all schemas
psql -h localhost -p 54320 -U savvi -d savvi_studio -c "\dn"
# List functions in schema
psql -h localhost -p 54320 -U savvi -d savvi_studio -c "\df my_schema.*"
# Check specific function
psql -h localhost -p 54320 -U savvi -d savvi_studio \
-c "\df my_schema.my_function"
Generation Issues
Force Clean Regeneration
# Remove all generated files
rm -rf src/__generated__
# Regenerate from scratch
pnpm db:codegen
# With verbose output
pnpm db:codegen --verbose
Check Generated Files
# List all generated files
find src/__generated__ -name "*.ts"
# Check specific schema
ls -la src/__generated__/graph/
# View specific file
cat src/__generated__/graph/index.ts
Debug with Verbose Output
# See all introspection queries
pnpm db:codegen --schema graph --verbose 2>&1 | tee codegen.log
# Filter for specific information
pnpm db:codegen --verbose 2>&1 | grep -A5 "Error"
pnpm db:codegen --verbose 2>&1 | grep "SELECT"
pnpm db:codegen --verbose 2>&1 | grep "Writing"
Type Error Fixes
Update Function Calls After Type Changes
// Before: Old signature
await myFunction(client, { p_id: '123' });
// After: Type changed to bigint
await myFunction(client, { p_id: 123n });
Find All Call Sites
# Search for function usage
grep -r "myFunction" src/
# With line numbers
grep -rn "myFunction" src/
# Exclude generated files
grep -r "myFunction" src/ --exclude-dir="__generated__"
Handle Missing Parameters
// ❌ Missing required param
await createUser(client, { p_name: 'John' });
// ✅ All required params
await createUser(client, {
p_email: 'john@example.com',
p_name: 'John'
});
Validation Error Handling
Basic Error Handling
import { ZodError } from 'zod';
try {
await myFunction(client, params);
} catch (error) {
if (error instanceof ZodError) {
console.error('Validation errors:', error.errors);
// [{ path: ['p_email'], message: 'Invalid email', ... }]
}
}
Detailed Error Inspection
import { ZodError } from 'zod';
try {
await createUser(client, untrustedParams);
} catch (error) {
if (error instanceof ZodError) {
for (const issue of error.errors) {
console.error(`Field: ${issue.path.join('.')}`);
console.error(`Error: ${issue.message}`);
console.error(`Expected: ${issue.expected}`);
console.error(`Received: ${issue.received}`);
}
}
}
Type-Safe Error Handling
import { ZodError } from 'zod';
import { DatabaseError } from 'pg';
async function safeCreateUser(params: unknown) {
try {
return await withClient(async (client) => {
return await createUser(client, params);
});
} catch (error) {
if (error instanceof ZodError) {
// Validation error - input was invalid
throw new ValidationError('Invalid user data', error.errors);
} else if (error instanceof DatabaseError) {
// Database error - constraint violation, etc
throw new DbOperationError('Failed to create user', error);
}
throw error;
}
}
Import Error Fixes
Restart TypeScript Server
// VS Code: Open Command Palette
// Cmd/Ctrl + Shift + P
// Type: "TypeScript: Restart TS Server"
// Press Enter
Verify tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"],
"@db": ["./src/__generated__/index.ts"],
"@db/*": ["./src/__generated__/*"]
}
}
}
Check Import Paths
// ✅ Correct imports
import { createResource } from '@db/graph';
import type { NodeData } from '@db/graph/types';
import { studio, auth, graph } from '@db';
// ❌ Wrong imports
import { createResource } from '@db/auth'; // Wrong schema
import { NodeData } from '@db/graph'; // Missing /types
import createResource from '@db/graph'; // Default import doesn't exist
CI/CD Troubleshooting
GitHub Actions Example
name: Codegen Check
on: [pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: pnpm install
- name: Start database
run: docker compose up -d postgres
- name: Wait for database
run: |
until psql $DATABASE_URL -c "SELECT 1" > /dev/null 2>&1; do
echo "Waiting for database..."
sleep 1
done
- name: Run migrations
run: pnpm db:reset
- name: Generate code
run: pnpm db:codegen
- name: Verify generated code
run: pnpm db:codegen --check
- name: Type check
run: pnpm tsc --noEmit
- name: Run tests
run: pnpm test
GitLab CI Example
codegen:
image: node:18
services:
- postgres:15
variables:
DATABASE_URL: "postgresql://postgres:password@postgres:5432/test"
before_script:
- pnpm install
- pnpm db:reset
script:
- pnpm db:codegen
- pnpm db:codegen --check
- pnpm tsc --noEmit
Mock Client for Testing
Basic Mock
import { vi } from 'vitest';
import type { PoolClient } from 'pg';
const mockClient = {
query: vi.fn().mockResolvedValue({
rows: [{ result: 123n }]
})
} as unknown as PoolClient;
// Use in test
const result = await myFunction(mockClient, params);
expect(mockClient.query).toHaveBeenCalledWith(
'SELECT my_function($1, $2)',
[param1, param2]
);
Advanced Mock with Multiple Calls
import { vi } from 'vitest';
const mockClient = {
query: vi.fn()
.mockResolvedValueOnce({ rows: [{ id: 1n }] })
.mockResolvedValueOnce({ rows: [{ id: 2n }] })
.mockResolvedValueOnce({ rows: [] })
} as any;
// First call returns id: 1n
// Second call returns id: 2n
// Third call returns empty array
Mock with Error
import { vi } from 'vitest';
import { DatabaseError } from 'pg';
const mockClient = {
query: vi.fn().mockRejectedValue(
new DatabaseError('unique constraint violation', 1, 'error')
)
} as any;
// Test error handling
await expect(myFunction(mockClient, params)).rejects.toThrow();
Integration Test Patterns
Using withTestClient
import { describe, it, expect } from 'vitest';
import { withTestClient } from '@/test/utils';
import { createResource, getResource } from '@db/graph';
describe('resource operations', () => {
it('creates and retrieves resource', async () => {
await withTestClient(async (client) => {
// Create resource
const id = await createResource(client, {
p_type_namespace: 'test.user',
p_data: { name: 'John' }
});
expect(id).toBeDefined();
// Retrieve resource
const resource = await getResource(client, { p_id: id });
expect(resource).toBeDefined();
expect(resource?.data).toEqual({ name: 'John' });
});
});
});
Transaction Testing
import { withTransaction } from '@/lib/db';
describe('transactional operations', () => {
it('rolls back on error', async () => {
await expect(
withTransaction(async (client) => {
await createResource(client, { /* ... */ });
throw new Error('Simulated error');
})
).rejects.toThrow('Simulated error');
// Verify rollback - resource should not exist
await withTestClient(async (client) => {
const count = await countResources(client);
expect(count).toBe(0n);
});
});
});
Performance Debugging
Check Query Execution Time
import { performance } from 'perf_hooks';
const start = performance.now();
await myFunction(client, params);
const end = performance.now();
console.log(`Execution time: ${end - start}ms`);
Profile Multiple Operations
import { performance } from 'perf_hooks';
async function profileOperations() {
const results: Record<string, number> = {};
for (const op of operations) {
const start = performance.now();
await op.execute();
results[op.name] = performance.now() - start;
}
console.table(results);
}
Database Query Logging
-- Enable query logging in PostgreSQL
ALTER DATABASE savvi_dev SET log_statement = 'all';
ALTER DATABASE savvi_dev SET log_duration = on;
-- View slow queries
SELECT * FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
Cache Issues
Clear and Regenerate
# Disable cache
pnpm db:codegen --no-cache
# Force regeneration (bypasses cache)
pnpm db:codegen --force
# Remove cache directory (if exists)
rm -rf .codegen-cache
pnpm db:codegen
IDE Not Updating
VS Code Troubleshooting
# 1. Regenerate code
pnpm db:codegen
# 2. Restart TypeScript server
# Cmd/Ctrl + Shift + P → "TypeScript: Restart TS Server"
# 3. Restart dev server
pnpm dev
# 4. If still not working, reload window
# Cmd/Ctrl + Shift + P → "Developer: Reload Window"
Check File Watchers
# Check if files are being watched
# macOS/Linux
lsof | grep "src/__generated__"
# Increase file watcher limit (Linux)
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Related Documentation
- Troubleshooting - Complete troubleshooting guide
- CLI Reference - CLI commands and options
- Usage - Development workflow
These examples demonstrate how to diagnose and fix common codegen issues.