| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Jenkins Error Explainer</title> |
| <style> |
| * { box-sizing: border-box; margin: 0; padding: 0; } |
| body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 40px 20px; } |
| .container { max-width: 800px; margin: 0 auto; background: white; border-radius: 16px; box-shadow: 0 20px 60px rgba(0,0,0,0.3); overflow: hidden; } |
| .header { background: linear-gradient(135deg, #4a90d9 0%, #5c3cb8 100%); color: white; padding: 30px; text-align: center; } |
| .header h1 { font-size: 28px; margin-bottom: 8px; } |
| .header p { opacity: 0.9; font-size: 14px; } |
| .content { padding: 30px; } |
| textarea { width: 100%; height: 200px; padding: 15px; border: 2px solid #e0e0e0; border-radius: 12px; font-family: 'Monaco', 'Menlo', monospace; font-size: 13px; resize: vertical; transition: border-color 0.3s; } |
| textarea:focus { outline: none; border-color: #667eea; } |
| .btn { display: block; width: 100%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 16px; font-size: 16px; font-weight: 600; border-radius: 12px; cursor: pointer; margin-top: 20px; transition: transform 0.2s, box-shadow 0.2s; } |
| .btn:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(102, 126, 234, 0.4); } |
| .btn:disabled { opacity: 0.7; cursor: not-allowed; transform: none; } |
| #result { margin-top: 30px; display: none; } |
| #result.show { display: block; animation: fadeIn 0.4s ease; } |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } |
| .error-category { display: inline-block; background: linear-gradient(135deg, #ff6b6b 0%, #ee5a5a 100%); color: white; padding: 8px 16px; border-radius: 20px; font-weight: 600; font-size: 14px; margin-bottom: 15px; } |
| .section { margin: 20px 0; } |
| .section h3 { color: #333; font-size: 16px; margin-bottom: 10px; } |
| .summary { background: #f8f9fa; padding: 15px; border-radius: 10px; line-height: 1.6; color: #555; } |
| .causes { background: #fff3e0; padding: 15px; border-radius: 10px; } |
| .causes ul { margin-left: 20px; color: #e65100; } |
| .causes li { margin: 8px 0; } |
| .references { background: #e8f5e9; padding: 15px; border-radius: 10px; } |
| .references ul { margin-left: 20px; color: #2e7d32; } |
| .references li { margin: 5px 0; } |
| .footer { background: #f5f5f5; padding: 20px; text-align: center; color: #888; font-size: 12px; } |
| </style> |
| </head> |
| <body> |
| <div class="container"> |
| <div class="header"> |
| <h1>🔧 Jenkins Error Explainer</h1> |
| <p>AI-powered Jenkins pipeline error diagnosis</p> |
| </div> |
| |
| <div class="content"> |
| <textarea id="logInput" placeholder="Paste your Jenkins error log here... |
| |
| Example: |
| Started by user admin |
| org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: |
| WorkflowScript: 10: expecting '}', found '' @ line 10, column 1 |
| "></textarea> |
| <button class="btn" onclick="explainError()" id="submitBtn">Analyze Error</button> |
| |
| <div id="result"> |
| <span class="error-category" id="category"></span> |
| |
| <div class="section"> |
| <h3>📝 Summary</h3> |
| <div class="summary" id="summary"></div> |
| </div> |
| |
| <div class="section"> |
| <h3>🔍 Likely Causes</h3> |
| <div class="causes"><ul id="causes"></ul></div> |
| </div> |
| |
| <div class="section"> |
| <h3>📚 References</h3> |
| <div class="references"><ul id="references"></ul></div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="footer"> |
| <p><strong>Architecture:</strong> RAG (Retrieval-Augmented Generation) using FAISS + LangChain</p> |
| <p>Built with ❤️ for Jenkins Developers</p> |
| </div> |
| </div> |
|
|
| <script> |
| const ERROR_DATABASE = { |
| groovy_syntax_error: { |
| category: "Groovy Syntax Error", |
| summary: "The pipeline failed due to a Groovy syntax error, most likely caused by an invalid or incomplete Jenkinsfile.", |
| causes: [ |
| "Missing or mismatched braces in the Jenkinsfile", |
| "Invalid declarative pipeline structure", |
| "Incorrect string quotes or special characters", |
| "Missing required keywords like 'pipeline', 'stages', or 'steps'" |
| ], |
| references: [ |
| "Pipeline Syntax Reference (Jenkins.io)", |
| "Declarative Pipeline Documentation", |
| "Groovy Language Documentation" |
| ] |
| }, |
| missing_agent: { |
| category: "Missing Agent", |
| summary: "The pipeline attempted to execute a step that requires a node, but no agent was allocated.", |
| causes: [ |
| "Using 'agent none' without defining a stage-level agent", |
| "Executing node-dependent steps (like 'sh', 'node') without a workspace", |
| "Missing agent directive in declarative pipeline" |
| ], |
| references: [ |
| "Agent Directive (Jenkins.io)", |
| "Pipeline Steps Documentation" |
| ] |
| }, |
| no_node_available: { |
| category: "No Node Available", |
| summary: "The pipeline could not be scheduled because no Jenkins node matched the requested label.", |
| causes: [ |
| "The specified node label does not exist", |
| "All matching nodes are offline or busy", |
| "No executors available on matching nodes", |
| "Node label typo or case mismatch" |
| ], |
| references: [ |
| "Distributed Builds (Jenkins.io)", |
| "Node Label Plugin Documentation", |
| "Label Selector Plugin" |
| ] |
| }, |
| missing_plugin: { |
| category: "Missing Plugin", |
| summary: "The pipeline referenced a step that is not available, indicating a missing or uninstalled plugin.", |
| causes: [ |
| "Required plugin is not installed", |
| "Plugin is installed but not enabled", |
| "Incorrect step name in the Jenkinsfile", |
| "Plugin version mismatch" |
| ], |
| references: [ |
| "Plugin Index", |
| "Pipeline Steps Reference", |
| "Managing Plugins Documentation" |
| ] |
| }, |
| missing_credentials: { |
| category: "Missing Credentials", |
| summary: "The pipeline referenced credentials that do not exist in Jenkins.", |
| causes: [ |
| "Credentials ID is incorrect or misspelled", |
| "Credentials were not configured in Jenkins", |
| "Credentials have expired or been deleted", |
| "User does not have permission to use the credentials" |
| ], |
| references: [ |
| "Credentials Plugin Documentation", |
| "Using Credentials in Pipelines", |
| "Credential Binding Plugin" |
| ] |
| }, |
| file_not_found: { |
| category: "File Not Found", |
| summary: "The pipeline attempted to access a file that does not exist in the workspace.", |
| causes: [ |
| "File path is incorrect or has typos", |
| "File was not generated in previous build step", |
| "File was not checked out from version control", |
| "Working directory mismatch" |
| ], |
| references: [ |
| "Pipeline Basic Steps", |
| "Workspace Plugin Documentation", |
| "File Operations Plugin" |
| ] |
| }, |
| git_authentication_error: { |
| category: "Git Authentication Error", |
| summary: "Jenkins failed to authenticate with the Git repository during checkout.", |
| causes: [ |
| "Invalid or missing Git credentials", |
| "SSH key not configured properly", |
| "Repository URL authentication method mismatch", |
| "Token has expired or been revoked" |
| ], |
| references: [ |
| "Git Plugin Documentation", |
| "Credential Binding Plugin", |
| "SSH Credentials Plugin" |
| ] |
| }, |
| timeout_error: { |
| category: "Timeout Error", |
| summary: "The pipeline or a step took too long to complete and was terminated.", |
| causes: [ |
| "Step execution time exceeded timeout limit", |
| "Network latency or connection issues", |
| "External service not responding", |
| "Build queue is too long causing delays" |
| ], |
| references: [ |
| "Timeout Step Documentation", |
| "Pipeline Timeout Configuration", |
| "Jenkins Queue Management" |
| ] |
| }, |
| out_of_memory: { |
| category: "Out of Memory", |
| summary: "The build failed due to insufficient memory allocation.", |
| causes: [ |
| "JVM heap size too small for the build", |
| "Memory leak in the application", |
| "Too many parallel builds consuming memory", |
| "Large file processing exceeding limits" |
| ], |
| references: [ |
| "JVM Memory Tuning", |
| "Pipeline Resource Management", |
| "Kubernetes Memory Limits" |
| ] |
| }, |
| permission_denied: { |
| category: "Permission Denied", |
| summary: "The pipeline attempted an operation without sufficient permissions.", |
| causes: [ |
| "Insufficient file system permissions", |
| "Missing role-based access control (RBAC) permissions", |
| "Pipeline lacks required approval or authorization", |
| "Security realm authentication failure" |
| ], |
| references: [ |
| "Matrix Authorization Strategy", |
| "Role-Based Access Control Plugin", |
| "Pipeline Security Documentation" |
| ] |
| }, |
| docker_error: { |
| category: "Docker Error", |
| summary: "The pipeline failed while building or running Docker containers.", |
| causes: [ |
| "Docker daemon not running or not accessible", |
| "Invalid Docker image name or tag", |
| "Dockerfile syntax errors", |
| "Insufficient permissions to pull images" |
| ], |
| references: [ |
| "Docker Pipeline Plugin", |
| "Dockerfile Reference", |
| "Kaniko vs Docker Build" |
| ] |
| }, |
| unknown: { |
| category: "Unknown Error", |
| summary: "The error could not be confidently identified. Please check the error message for more details.", |
| causes: [ |
| "Review the full error log for specific details", |
| "Check Jenkins system logs for more information", |
| "Search Jenkins community forums for the error", |
| "Contact Jenkins administrators for help" |
| ], |
| references: [ |
| "Jenkins Pipeline Troubleshooting Guide", |
| "Jenkins Users Mailing List", |
| "Jenkins Community Forum" |
| ] |
| } |
| }; |
| |
| function detectErrorCategory(log) { |
| const lower = log.toLowerCase(); |
| |
| if (lower.includes('groovy') && (lower.includes('syntax') || lower.includes('expecting') || lower.includes('failed'))) { |
| return 'groovy_syntax_error'; |
| } |
| if (lower.includes('agent') && (lower.includes('none') || lower.includes('null'))) { |
| return 'missing_agent'; |
| } |
| if (lower.includes('no node') || lower.includes('no such agent') || lower.includes('label')) { |
| return 'no_node_available'; |
| } |
| if (lower.includes('no such dsl') || lower.includes('undefined method') || lower.includes('not a valid step')) { |
| return 'missing_plugin'; |
| } |
| if (lower.includes('credentials') && (lower.includes('not found') || lower.includes('null') || lower.includes('missing'))) { |
| return 'missing_credentials'; |
| } |
| if (lower.includes('file not found') || lower.includes('no such file') || lower.includes('does not exist')) { |
| return 'file_not_found'; |
| } |
| if ((lower.includes('git') || lower.includes('checkout')) && (lower.includes('authentication') || lower.includes('failed') || lower.includes('permission'))) { |
| return 'git_authentication_error'; |
| } |
| if (lower.includes('timeout') || lower.includes('timed out') || lower.includes('deadline exceeded')) { |
| return 'timeout_error'; |
| } |
| if (lower.includes('outofmemory') || lower.includes('out of memory') || lower.includes('heap space') || lower.includes('oom')) { |
| return 'out_of_memory'; |
| } |
| if (lower.includes('permission denied') || lower.includes('access denied') || lower.includes('unauthorized')) { |
| return 'permission_denied'; |
| } |
| if (lower.includes('docker') && (lower.includes('error') || lower.includes('failed') || lower.includes('not found'))) { |
| return 'docker_error'; |
| } |
| return 'unknown'; |
| } |
| |
| function explainError() { |
| const logText = document.getElementById('logInput').value; |
| const resultDiv = document.getElementById('result'); |
| const btn = document.getElementById('submitBtn'); |
| |
| if (!logText.trim()) { |
| alert('Please provide a Jenkins error log.'); |
| return; |
| } |
| |
| btn.disabled = true; |
| btn.textContent = 'Analyzing...'; |
| |
| setTimeout(() => { |
| const category = detectErrorCategory(logText); |
| const info = ERROR_DATABASE[category]; |
| |
| document.getElementById('category').textContent = info.category; |
| document.getElementById('summary').textContent = info.summary; |
| document.getElementById('causes').innerHTML = info.causes.map(c => `<li>${c}</li>`).join(''); |
| document.getElementById('references').innerHTML = info.references.map(r => `<li>${r}</li>`).join(''); |
| |
| resultDiv.classList.add('show'); |
| |
| btn.disabled = false; |
| btn.textContent = 'Analyze Error'; |
| }, 500); |
| } |
| </script> |
| </body> |
| </html> |
|
|