- Created `/frontend/app/api/votes/check/route.ts` to handle GET requests for checking if a user has voted in a specific election. - Added error handling for unauthorized access and missing election ID. - Forwarded requests to the backend API and returned appropriate responses. - Updated `/frontend/app/api/votes/history/route.ts` to fetch user's voting history with error handling. - Ensured both endpoints utilize the authorization token for secure access.
12 KiB
12 KiB
🔍 Advanced Logging - Blockchain Dashboard Diagnostics
Status: Comprehensive logging added
Purpose: Identify exact source of undefined hash error
📊 Logging Points Added
1. BlockchainPage Component (/frontend/app/dashboard/blockchain/page.tsx)
// Log when fetching starts
console.log("[BlockchainPage] Fetching blockchain for election:", selectedElection)
// Log fetch response
console.log("[BlockchainPage] Fetch response status:", response.status)
// Log empty blockchain
console.log("[BlockchainPage] No blockchain found (404), creating empty state")
// Log received data structure
console.log("[BlockchainPage] Received blockchain data:", {
blocksCount: data?.blocks?.length || 0,
hasVerification: !!data?.verification,
firstBlockStructure: { index, transaction_id, encrypted_vote, signature }
})
// Log errors
console.error("[BlockchainPage] Error fetching blockchain:", errorMessage)
// Log mock data
console.log("[BlockchainPage] Using mock data")
What to look for:
[BlockchainPage] Fetching blockchain for election: 1
[BlockchainPage] Fetch response status: 200
[BlockchainPage] Received blockchain data: {
blocksCount: 5,
hasVerification: true,
firstBlockStructure: {
index: 0,
transaction_id: "genesis",
encrypted_vote: "",
signature: ""
}
}
2. BlockchainVisualizer Component (/frontend/components/blockchain-visualizer.tsx)
Main Component Logging
// Log component mount/update
console.log("[BlockchainVisualizer] Component mounted/updated", {
dataExists: !!data,
isValidData,
blocksCount: data?.blocks?.length || 0,
isLoading,
isVerifying,
})
// Log first block structure in detail
console.log("[BlockchainVisualizer] First block structure:", {
index, transaction_id, prev_hash, block_hash,
encrypted_vote, signature, timestamp
})
// Log each block's critical fields
console.log(`Block ${idx}:`, {
transaction_id,
encrypted_vote_empty: block.encrypted_vote === "",
signature_empty: block.signature === "",
})
What to look for:
[BlockchainVisualizer] Component mounted/updated {
dataExists: true,
isValidData: true,
blocksCount: 5,
isLoading: false,
isVerifying: false
}
[BlockchainVisualizer] First block structure: {
index: 0,
transaction_id: "genesis",
encrypted_vote: "", ← Empty string, not undefined!
signature: "", ← Empty string, not undefined!
block_hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
Block 0: { transaction_id: "genesis", encrypted_vote_empty: true, signature_empty: true }
TruncateHash Logging
const truncateHash = (hash, length) => {
console.log(`[truncateHash] Called with:`, {
hash,
type: typeof hash,
isNull: hash === null,
isUndefined: hash === undefined,
isEmpty: hash === "",
length: hash?.length || 0,
requestedLength: length,
})
if (hash === null || hash === undefined) {
console.warn(`[truncateHash] Received ${hash === null ? "null" : "undefined"}`)
return "N/A"
}
if (typeof hash !== "string") {
console.error(`[truncateHash] Invalid type: ${typeof hash}, value: ${hash}`)
return "N/A"
}
if (hash.length === 0) {
console.log(`[truncateHash] Empty string received`)
return "N/A"
}
const result = hash.length > length ? `${hash.slice(0, length)}...` : hash
console.log(`[truncateHash] Result:`, result)
return result
}
What to look for:
✅ CORRECT:
[truncateHash] Called with: {
hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
type: "string",
isNull: false,
isUndefined: false,
isEmpty: false,
length: 64,
requestedLength: 12
}
[truncateHash] Result: e3b0c442...
❌ PROBLEM (What we're trying to find):
[truncateHash] Called with: {
hash: undefined,
type: "undefined",
isNull: false,
isUndefined: true,
isEmpty: false,
length: 0,
requestedLength: 16
}
[truncateHash] Received undefined
3. BlockchainViewer Component (/frontend/components/blockchain-viewer.tsx)
// Log component mount
console.log("[BlockchainViewer] Component mounted/updated", {
dataExists: !!data,
blocksCount: data?.blocks?.length || 0,
isLoading,
isVerifying,
})
// Log truncateHash calls
console.warn("[BlockchainViewer] truncateHash received invalid value:", { hash, type: typeof hash })
What to look for:
[BlockchainViewer] Component mounted/updated {
dataExists: true,
blocksCount: 5,
isLoading: false,
isVerifying: false
}
🔎 How to Check the Logs
Step 1: Open Browser DevTools
Press F12 → Console Tab
Step 2: Refresh Blockchain Page
Navigate to: http://localhost:3000/dashboard/blockchain
Step 3: Select an Election
Click dropdown and select: "Election Présidentielle 2025"
Wait for blockchain to load
Step 4: Look for Log Messages
All logs start with [ComponentName] for easy filtering:
[BlockchainPage]- Page component logs[BlockchainVisualizer]- Visualizer component logs[BlockchainViewer]- Viewer component logs[truncateHash]- Hash truncation function logs
Step 5: Filter Logs
In browser console, type:
// Search for truncateHash issues
filter: "[truncateHash]"
// Search for visualizer issues
filter: "[BlockchainVisualizer]"
// Search for page issues
filter: "[BlockchainPage]"
📋 Expected vs Problematic Output
✅ EXPECTED (Good):
[BlockchainPage] Fetching blockchain for election: 1
[BlockchainPage] Fetch response status: 200
[BlockchainPage] Received blockchain data: {
blocksCount: 5,
hasVerification: true,
firstBlockStructure: { index: 0, transaction_id: "genesis", ... }
}
[BlockchainVisualizer] Component mounted/updated {
dataExists: true,
isValidData: true,
blocksCount: 5
}
[BlockchainVisualizer] First block structure: {
index: 0,
transaction_id: "genesis",
encrypted_vote: "",
signature: ""
}
Block 0: { transaction_id: "genesis", encrypted_vote_empty: true, signature_empty: true }
[truncateHash] Called with: { hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", type: "string", isEmpty: false, ... }
[truncateHash] Result: e3b0c442...
[truncateHash] Called with: { hash: "", type: "string", isEmpty: true, ... }
[truncateHash] Empty string received
[truncateHash] Result: N/A
❌ PROBLEMATIC (What we're looking for):
[BlockchainVisualizer] First block structure: {
index: 0,
transaction_id: undefined, ← ⚠️ UNDEFINED!
encrypted_vote: undefined, ← ⚠️ UNDEFINED!
signature: undefined ← ⚠️ UNDEFINED!
}
[truncateHash] Called with: { hash: undefined, type: "undefined", isUndefined: true, ... }
[truncateHash] Received undefined
🎯 Diagnosis Checklist
-
Is the blockchain data being fetched?
- Check for
[BlockchainPage] Fetching blockchain...log - Check for
[BlockchainPage] Fetch response status: 200log
- Check for
-
Is the data structure correct?
- Check
[BlockchainVisualizer] First block structurelog - Verify all fields are strings or empty strings, NOT undefined
- Check
-
Where is truncateHash being called with undefined?
- Filter console for
[truncateHash] Called with - Look for any calls with
isUndefined: true - Check the CALL STACK to see which code called it
- Filter console for
-
Is the problem in the data or in the rendering?
- If data shows undefined → Backend issue
- If data shows correct but rendering still fails → React rendering issue
🔄 Data Flow Trace
User opens dashboard
↓ logs: [BlockchainPage] Fetching...
↓
Backend returns data
↓ logs: [BlockchainPage] Received blockchain data
↓
Component mounts
↓ logs: [BlockchainVisualizer] Component mounted
↓
First block logged
↓ logs: [BlockchainVisualizer] First block structure
↓
Rendering starts
↓ logs: [truncateHash] Called with... (for each hash field)
↓
If undefined → ERROR logged here
↓ logs: [truncateHash] Received undefined
🛠️ Copy-Paste Filter Commands
Filter for truncateHash errors:
// In console, run:
console.clear()
// Then search: "[truncateHash]"
Filter for page issues:
console.clear()
// Then search: "[BlockchainPage]"
Filter for all blockchain logs:
console.clear()
// Then search: "[Blockchain"
Export logs to see all:
// Copy all console logs
copy(document.querySelector('.console-messages').innerHTML)
📊 Log Output Examples
Example 1: Successful Load
[BlockchainPage] Fetching blockchain for election: 1
[BlockchainPage] Fetch response status: 200
[BlockchainPage] Received blockchain data: {
blocksCount: 3,
hasVerification: true,
firstBlockStructure: {
index: 0,
transaction_id: "genesis",
encrypted_vote: "",
signature: ""
}
}
[BlockchainVisualizer] Component mounted/updated {
dataExists: true,
isValidData: true,
blocksCount: 3,
isLoading: false,
isVerifying: false
}
[BlockchainVisualizer] First block structure: {
index: 0,
transaction_id: "genesis",
prev_hash: "0000000000000000000000000000000000000000000000000000000000000000",
block_hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
encrypted_vote: "",
signature: "",
timestamp: 1731219600
}
Block 0: { transaction_id: "genesis", encrypted_vote_empty: true, signature_empty: true }
[truncateHash] Called with: { hash: "genesis", type: "string", isNull: false, isUndefined: false, isEmpty: false, length: 7, requestedLength: 20 }
[truncateHash] Result: genesis
[truncateHash] Called with: { hash: "0000000000000000000000000000000000000000000000000000000000000000", type: "string", isNull: false, isUndefined: false, isEmpty: false, length: 64, requestedLength: 12 }
[truncateHash] Result: 000000000000...
Example 2: Problem Case (If you see this)
[BlockchainPage] Fetching blockchain for election: 1
[BlockchainPage] Fetch response status: 200
[BlockchainPage] Received blockchain data: {
blocksCount: 3,
hasVerification: true,
firstBlockStructure: {
index: 0,
transaction_id: undefined, ← ⚠️ PROBLEM!
encrypted_vote: undefined, ← ⚠️ PROBLEM!
signature: undefined ← ⚠️ PROBLEM!
}
}
[truncateHash] Called with: { hash: undefined, type: "undefined", isUndefined: true, ... }
[truncateHash] Received undefined
🎓 What Each Log Tells Us
| Log | Means | Next Action |
|---|---|---|
[BlockchainPage] Fetching... |
API request starting | ✅ Good, wait for response |
[BlockchainPage] Fetch response status: 200 |
Data received | ✅ Good, check data structure |
[BlockchainPage] Received blockchain data... |
Parsing data | Check if blocks have values |
[BlockchainVisualizer] Component mounted |
Component rendering | ✅ Good, check data passed to it |
[truncateHash] Called with: { hash: "abc"... } |
Truncating hash | ✅ Good, function working |
[truncateHash] Called with: { hash: undefined... } |
❌ Problem! | Data has undefined fields |
[truncateHash] Empty string received |
Field was empty "" | ✅ Good, returns "N/A" |
[truncateHash] Result: N/A |
Handled undefined | ✅ Good, graceful fallback |
🚀 Next Steps
-
Rebuild frontend with new logging:
docker compose restart frontend sleep 5 -
Open browser console (F12)
-
Navigate to dashboard/blockchain
-
Select an election
-
Copy all logs and share them
-
Look for any
undefinedvalues in the data structure logs
💡 Tips for Debugging
If you see truncateHash errors:
- Look at the
[truncateHash] Called withlog - Check if
isUndefined: true - If yes, look at the PREVIOUS logs to see where undefined came from
If data looks correct but still errors:
- Check if there's a component NOT using the logging version
- Check if code was rebuilt properly
- Clear browser cache (Ctrl+Shift+Del)
If you can't find the logs:
- Make sure to click "Console" tab (not Elements/Network)
- Refresh page with F5
- Try filtering with:
Ctrl+Fthen type[truncateHash]
Logging Points: ✅ Added
Ready to: Diagnose the issue
Next: Run the app and check console output