@boundless-oss/atlas
Version:
Atlas - MCP Server for comprehensive startup project management
362 lines • 13.6 kB
JavaScript
export function setupErrorsAPI(app, errorHandler) {
// Error analysis API endpoints setup
// Get error timeline
app.get('/api/errors/timeline', async (req, res) => {
try {
const { timeRange = '24h', toolName, severity, includeContext = 'true', limit = 100, offset = 0 } = req.query;
const options = {
timeRange: timeRange,
toolName: toolName,
severity: severity,
includeContext: includeContext === 'true',
limit: Number(limit),
offset: Number(offset)
};
const timeline = await errorHandler.getErrorTimeline(options);
res.json({
success: true,
data: {
timeline,
count: timeline.length,
options
},
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error fetching error timeline:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch error timeline',
message: error.message
});
}
});
// Get error patterns analysis
app.get('/api/errors/patterns', async (req, res) => {
try {
const { timeRange = '24h', errorTypes, minOccurrences = '2', groupBy = 'type' } = req.query;
const options = {
timeRange: timeRange,
errorTypes: errorTypes ? errorTypes.split(',') : undefined,
minOccurrences: Number(minOccurrences),
groupBy: groupBy
};
const patterns = await errorHandler.analyzeErrorPatterns(options);
res.json({
success: true,
data: patterns,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error analyzing error patterns:', error);
res.status(500).json({
success: false,
error: 'Failed to analyze error patterns',
message: error.message
});
}
});
// Get specific error details
app.get('/api/errors/detail/:id', async (req, res) => {
try {
const { id } = req.params;
const { includeContext = 'true', includeSuggestions = 'true' } = req.query;
const errorDetails = await errorHandler.getErrorDetails(id);
if (!errorDetails) {
return res.status(404).json({
success: false,
error: 'Error not found',
errorId: id
});
}
res.json({
success: true,
data: errorDetails,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error(`🐛 Error fetching error details for ${req.params.id}:`, error);
res.status(500).json({
success: false,
error: 'Failed to fetch error details',
message: error.message
});
}
});
// Generate error report
app.get('/api/errors/report', async (req, res) => {
try {
const { reportType = 'summary', timeRange = '24h', includeRecommendations = 'true', outputFormat = 'json' } = req.query;
const options = {
reportType: reportType,
timeRange: timeRange,
includeRecommendations: includeRecommendations === 'true',
outputFormat: outputFormat,
saveToFile: false
};
const report = await errorHandler.generateErrorReport(options);
if (outputFormat === 'json') {
res.json({
success: true,
data: report,
timestamp: new Date().toISOString()
});
}
else {
// For markdown or other formats, return as text
res.setHeader('Content-Type', 'text/plain');
res.send(report.content || report);
}
}
catch (error) {
console.error('🐛 Error generating error report:', error);
res.status(500).json({
success: false,
error: 'Failed to generate error report',
message: error.message
});
}
});
// Get error statistics and metrics
app.get('/api/errors/stats', async (req, res) => {
try {
const { timeRange = '24h' } = req.query;
// Get patterns to calculate statistics
const patterns = await errorHandler.analyzeErrorPatterns({
timeRange: timeRange,
minOccurrences: 1,
groupBy: 'type'
});
const timeline = await errorHandler.getErrorTimeline({
timeRange: timeRange
});
// Calculate statistics
const errorsByType = timeline.reduce((acc, error) => {
acc[error.type] = (acc[error.type] || 0) + 1;
return acc;
}, {});
const errorsBySeverity = timeline.reduce((acc, error) => {
acc[error.severity] = (acc[error.severity] || 0) + 1;
return acc;
}, {});
const errorsByTool = timeline.reduce((acc, error) => {
const tool = error.tool || 'unknown';
acc[tool] = (acc[tool] || 0) + 1;
return acc;
}, {});
const stats = {
timeRange,
totalErrors: timeline.length,
errorsByType,
errorsBySeverity,
errorsByTool,
patternsFound: patterns.patternsFound?.length || 0,
errorRate: calculateErrorRate(timeline, timeRange),
mostCommonError: Object.keys(errorsByType).reduce((a, b) => errorsByType[a] > errorsByType[b] ? a : b, 'none'),
criticalErrors: timeline.filter((e) => e.severity === 'critical').length,
trends: {
increasing: patterns.patternsFound?.filter((p) => p.trend === 'increasing').length || 0,
stable: patterns.patternsFound?.filter((p) => p.trend === 'stable').length || 0,
decreasing: patterns.patternsFound?.filter((p) => p.trend === 'decreasing').length || 0
}
};
res.json({
success: true,
data: stats,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error fetching error statistics:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch error statistics',
message: error.message
});
}
});
// Resolve error suggestion
app.post('/api/errors/resolve', async (req, res) => {
try {
const { errorId, suggestionId, implementation, effectiveness, notes } = req.body;
if (!errorId || !suggestionId) {
return res.status(400).json({
success: false,
error: 'Error ID and suggestion ID are required'
});
}
const resolution = await errorHandler.resolveErrorSuggestion({
errorId,
suggestionId,
implementation,
effectiveness,
notes
});
res.json({
success: true,
message: 'Error suggestion resolved successfully',
data: resolution,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error resolving error suggestion:', error);
res.status(500).json({
success: false,
error: 'Failed to resolve error suggestion',
message: error.message
});
}
});
// Simulate error recovery
app.post('/api/errors/simulate', async (req, res) => {
try {
const { errorType, severity = 'medium', context = {}, dryRun = true } = req.body;
if (!errorType) {
return res.status(400).json({
success: false,
error: 'Error type is required for simulation'
});
}
const simulation = await errorHandler.simulateErrorRecovery({
errorType,
severity,
context,
dryRun
});
res.json({
success: true,
data: simulation,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error simulating error recovery:', error);
res.status(500).json({
success: false,
error: 'Failed to simulate error recovery',
message: error.message
});
}
});
// Get error resolution suggestions
app.get('/api/errors/suggestions/:id', async (req, res) => {
try {
const { id } = req.params;
const errorDetails = await errorHandler.getErrorDetails(id);
if (!errorDetails) {
return res.status(404).json({
success: false,
error: 'Error not found',
errorId: id
});
}
res.json({
success: true,
data: {
errorId: id,
suggestions: errorDetails.suggestions || [],
rootCause: errorDetails.rootCause,
relatedErrors: errorDetails.relatedErrors || []
},
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error(`🐛 Error fetching suggestions for error ${req.params.id}:`, error);
res.status(500).json({
success: false,
error: 'Failed to fetch error suggestions',
message: error.message
});
}
});
// Get error trends over time
app.get('/api/errors/trends', async (req, res) => {
try {
const { timeRange = '7d', granularity = 'hour', errorType, toolName } = req.query;
// Return empty trend data when not implemented
const trendData = {
timeRange: timeRange || '24h',
granularity: granularity || 'hour',
errorType: errorType || 'all',
toolName: toolName || 'all',
dataPoints: [],
summary: {
totalErrors: 0,
averageErrorRate: 0,
peakErrorRate: 0,
trend: 'stable'
}
};
res.json({
success: true,
data: trendData,
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error fetching error trends:', error);
res.status(500).json({
success: false,
error: 'Failed to fetch error trends',
message: error.message
});
}
});
// Health check for error analysis service
app.get('/api/errors/health', async (req, res) => {
try {
// Test error handler functionality
const testPatterns = await errorHandler.analyzeErrorPatterns({
timeRange: '1h',
minOccurrences: 1,
groupBy: 'type'
});
res.json({
success: true,
status: 'healthy',
data: {
errorHandlerAvailable: true,
patternAnalysisWorking: testPatterns ? true : false,
features: {
errorTimeline: true,
patternAnalysis: true,
errorDetails: true,
reportGeneration: true,
resolutionTracking: true,
errorSimulation: true
}
},
timestamp: new Date().toISOString()
});
}
catch (error) {
console.error('🐛 Error service health check failed:', error);
res.status(503).json({
success: false,
status: 'unhealthy',
error: 'Error analysis service is not functioning properly',
message: error.message,
timestamp: new Date().toISOString()
});
}
});
}
function calculateErrorRate(timeline, timeRange) {
if (timeline.length === 0)
return 0;
// Calculate errors per hour based on time range
const hours = {
'1h': 1,
'6h': 6,
'24h': 24,
'7d': 24 * 7,
'30d': 24 * 30
}[timeRange] || 24;
return Number((timeline.length / hours).toFixed(2));
}
//# sourceMappingURL=errors.js.map