CIA/e-voting-system/.claude/DETAILED_LOGGING_GUIDE.md
E-Voting Developer 3efdabdbbd fix: Implement vote check endpoint in frontend API proxy
- 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.
2025-11-10 02:56:47 +01:00

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

  1. Is the blockchain data being fetched?

    • Check for [BlockchainPage] Fetching blockchain... log
    • Check for [BlockchainPage] Fetch response status: 200 log
  2. Is the data structure correct?

    • Check [BlockchainVisualizer] First block structure log
    • Verify all fields are strings or empty strings, NOT undefined
  3. 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
  4. 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

  1. Rebuild frontend with new logging:

    docker compose restart frontend
    sleep 5
    
  2. Open browser console (F12)

  3. Navigate to dashboard/blockchain

  4. Select an election

  5. Copy all logs and share them

  6. Look for any undefined values in the data structure logs


💡 Tips for Debugging

If you see truncateHash errors:

  1. Look at the [truncateHash] Called with log
  2. Check if isUndefined: true
  3. If yes, look at the PREVIOUS logs to see where undefined came from

If data looks correct but still errors:

  1. Check if there's a component NOT using the logging version
  2. Check if code was rebuilt properly
  3. Clear browser cache (Ctrl+Shift+Del)

If you can't find the logs:

  1. Make sure to click "Console" tab (not Elements/Network)
  2. Refresh page with F5
  3. Try filtering with: Ctrl+F then type [truncateHash]

Logging Points: Added
Ready to: Diagnose the issue
Next: Run the app and check console output