@toponextech/smartembed-mcp-server
Version:
MCP server for intelligent embedded development with PlatformIO - AI-powered project creation, error diagnosis, and device detection
267 lines • 9.34 kB
JavaScript
/**
* Error Parser for SmartEmbed
* Parses compilation errors and extracts structured information
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.ErrorParser = exports.ErrorSeverity = exports.ErrorCategory = exports.ErrorType = void 0;
var ErrorType;
(function (ErrorType) {
ErrorType["COMPILATION"] = "compilation";
ErrorType["LINKING"] = "linking";
ErrorType["SYNTAX"] = "syntax";
ErrorType["DECLARATION"] = "declaration";
ErrorType["LIBRARY"] = "library";
ErrorType["BOARD"] = "board";
ErrorType["MEMORY"] = "memory";
ErrorType["PERMISSION"] = "permission";
ErrorType["UNKNOWN"] = "unknown";
})(ErrorType || (exports.ErrorType = ErrorType = {}));
var ErrorCategory;
(function (ErrorCategory) {
ErrorCategory["BUILD"] = "build";
ErrorCategory["UPLOAD"] = "upload";
ErrorCategory["LIBRARY"] = "library";
ErrorCategory["CONFIGURATION"] = "configuration";
ErrorCategory["HARDWARE"] = "hardware";
})(ErrorCategory || (exports.ErrorCategory = ErrorCategory = {}));
var ErrorSeverity;
(function (ErrorSeverity) {
ErrorSeverity["ERROR"] = "error";
ErrorSeverity["WARNING"] = "warning";
ErrorSeverity["FATAL"] = "fatal";
})(ErrorSeverity || (exports.ErrorSeverity = ErrorSeverity = {}));
// Common error patterns
const ERROR_PATTERNS = [
// Compilation errors
{
pattern: /error:\s*'([^']+)'\s+was not declared in this scope/i,
type: ErrorType.DECLARATION,
extract: (match) => ({
message: `'${match[1]}' was not declared in this scope`,
details: { undeclared: match[1] },
}),
},
{
pattern: /error:\s*'([^']+)'\s+does not name a type/i,
type: ErrorType.DECLARATION,
extract: (match) => ({
message: `'${match[1]}' does not name a type`,
details: { unknownType: match[1] },
}),
},
{
pattern: /fatal error:\s*([^:]+):\s*No such file or directory/i,
type: ErrorType.LIBRARY,
extract: (match) => ({
message: `Missing header file: ${match[1]}`,
details: { missingFile: match[1] },
}),
},
// Library errors
{
pattern: /Library Manager:\s*([^@]+)@([^\s]+)\s+is already installed/i,
type: ErrorType.LIBRARY,
extract: (match) => ({
message: `Library ${match[1]} version ${match[2]} is already installed`,
details: { library: match[1], version: match[2] },
}),
},
{
pattern: /Error:\s*Could not find the package with '([^']+)' requirements/i,
type: ErrorType.LIBRARY,
extract: (match) => ({
message: `Could not find package with requirements: ${match[1]}`,
details: { requirements: match[1] },
}),
},
// Board/Platform errors
{
pattern: /Error:\s*Unknown board ID '([^']+)'/i,
type: ErrorType.BOARD,
extract: (match) => ({
message: `Unknown board ID: ${match[1]}`,
details: { boardId: match[1] },
}),
},
{
pattern: /Platform Manager:\s*platform '([^']+)' is not installed/i,
type: ErrorType.BOARD,
extract: (match) => ({
message: `Platform '${match[1]}' is not installed`,
details: { platform: match[1] },
}),
},
// Memory errors
{
pattern: /region\s+`([^']+)'\s+overflowed by\s+(\d+)\s+bytes/i,
type: ErrorType.MEMORY,
extract: (match) => ({
message: `Memory region '${match[1]}' overflowed by ${match[2]} bytes`,
details: { region: match[1], overflow: parseInt(match[2]) },
}),
},
// Upload/Permission errors
{
pattern: /error opening ([^:]+):\s*([^:]+)/i,
type: ErrorType.PERMISSION,
extract: (match) => ({
message: `Error opening ${match[1]}: ${match[2]}`,
details: { port: match[1], reason: match[2] },
}),
},
{
pattern: /Access is denied|Permission denied/i,
type: ErrorType.PERMISSION,
extract: () => ({
message: 'Permission denied when accessing device',
details: {},
}),
},
// Syntax errors
{
pattern: /error:\s*expected\s*'([^']+)'\s*before\s*'([^']+)'/i,
type: ErrorType.SYNTAX,
extract: (match) => ({
message: `Expected '${match[1]}' before '${match[2]}'`,
details: { expected: match[1], found: match[2] },
}),
},
{
pattern: /error:\s*stray\s*'\\(\d+)'\s*in program/i,
type: ErrorType.SYNTAX,
extract: (match) => ({
message: `Stray character '\\${match[1]}' in program`,
details: { character: `\\${match[1]}` },
}),
},
// Linking errors
{
pattern: /undefined reference to\s*`([^']+)'/i,
type: ErrorType.LINKING,
extract: (match) => ({
message: `Undefined reference to '${match[1]}'`,
details: { symbol: match[1] },
}),
},
{
pattern: /multiple definition of\s*`([^']+)'/i,
type: ErrorType.LINKING,
extract: (match) => ({
message: `Multiple definition of '${match[1]}'`,
details: { symbol: match[1] },
}),
},
];
// File location patterns
const FILE_LOCATION_PATTERNS = [
// GCC/G++ style: file.cpp:123:45: error:
/^([^:]+):(\d+):(\d+):\s*(error|warning|fatal error):/,
// Alternative style: In file included from file.cpp:123:
/In file included from ([^:]+):(\d+):/,
// Simple style: file.cpp:123: error:
/^([^:]+):(\d+):\s*(error|warning):/,
];
class ErrorParser {
/**
* Parse error output into structured format
*/
parse(errorOutput) {
const errors = [];
const lines = errorOutput.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
if (!line)
continue;
// Try to extract file location
let fileInfo = {};
for (const pattern of FILE_LOCATION_PATTERNS) {
const match = line.match(pattern);
if (match) {
fileInfo = {
file: match[1],
line: match[2] ? parseInt(match[2]) : undefined,
column: match[3] && !isNaN(parseInt(match[3])) ? parseInt(match[3]) : undefined,
};
break;
}
}
// Try to match error patterns
let errorInfo = null;
let errorType = ErrorType.UNKNOWN;
for (const { pattern, type, extract } of ERROR_PATTERNS) {
const match = line.match(pattern);
if (match) {
errorInfo = extract(match);
errorType = type;
break;
}
}
// If we found an error pattern or this line contains error/warning
if (errorInfo || /error:|warning:|fatal error:/i.test(line)) {
const severity = /fatal error:/i.test(line) ? ErrorSeverity.FATAL :
/warning:/i.test(line) ? ErrorSeverity.WARNING :
ErrorSeverity.ERROR;
const category = this.categorizeError(errorType);
errors.push({
type: errorType,
file: fileInfo.file,
line: fileInfo.line,
column: fileInfo.column,
message: errorInfo?.message || this.cleanErrorMessage(line),
rawError: line,
category,
severity,
...errorInfo?.details,
});
}
}
return errors;
}
/**
* Categorize error type into broader categories
*/
categorizeError(type) {
switch (type) {
case ErrorType.COMPILATION:
case ErrorType.SYNTAX:
case ErrorType.DECLARATION:
case ErrorType.LINKING:
case ErrorType.MEMORY:
return ErrorCategory.BUILD;
case ErrorType.LIBRARY:
return ErrorCategory.LIBRARY;
case ErrorType.BOARD:
return ErrorCategory.CONFIGURATION;
case ErrorType.PERMISSION:
return ErrorCategory.UPLOAD;
default:
return ErrorCategory.BUILD;
}
}
/**
* Clean error message by removing file location and prefixes
*/
cleanErrorMessage(line) {
return line
.replace(/^[^:]+:\d+(:\d+)?:\s*(error|warning|fatal error):\s*/i, '')
.replace(/^\s*\^+\s*$/, '') // Remove caret indicators
.trim();
}
/**
* Aggregate similar errors
*/
aggregateErrors(errors) {
const groups = new Map();
for (const error of errors) {
const key = `${error.type}:${error.message}`;
if (!groups.has(key)) {
groups.set(key, []);
}
groups.get(key).push(error);
}
return groups;
}
}
exports.ErrorParser = ErrorParser;
//# sourceMappingURL=error-parser.js.map
;