-
Notifications
You must be signed in to change notification settings - Fork 0
Improved error detection BEN-1078 #28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,6 +3,7 @@ import { benchifyFileSchema } from './schemas'; | |||||||||||||||||||||||||||||
import { z } from 'zod'; | ||||||||||||||||||||||||||||||
import { fetchAllSandboxFiles } from './file-filter'; | ||||||||||||||||||||||||||||||
import { applyTransformations } from './sandbox-helpers'; | ||||||||||||||||||||||||||||||
import { detectCodeErrors, parseTypeScriptErrors } from './error-detection'; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
const E2B_API_KEY = process.env.E2B_API_KEY; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -59,8 +60,11 @@ export async function createSandbox({ files }: { files: z.infer<typeof benchifyF | |||||||||||||||||||||||||||||
console.log('New packages installed successfully:', result.stdout); | ||||||||||||||||||||||||||||||
if (result.stderr) { | ||||||||||||||||||||||||||||||
console.warn('npm install warnings:', result.stderr); | ||||||||||||||||||||||||||||||
// Parse npm install errors | ||||||||||||||||||||||||||||||
if (result.stderr.includes('npm ERR!')) { | ||||||||||||||||||||||||||||||
// Only treat critical npm errors as build errors (not warnings or peer dep issues) | ||||||||||||||||||||||||||||||
if (result.stderr.includes('npm ERR!') && | ||||||||||||||||||||||||||||||
(result.stderr.includes('ENOTFOUND') || | ||||||||||||||||||||||||||||||
result.stderr.includes('ECONNREFUSED') || | ||||||||||||||||||||||||||||||
result.stderr.includes('permission denied'))) { | ||||||||||||||||||||||||||||||
buildErrors.push({ | ||||||||||||||||||||||||||||||
type: 'build', | ||||||||||||||||||||||||||||||
message: 'Package installation failed: ' + result.stderr.split('npm ERR!')[1]?.trim() | ||||||||||||||||||||||||||||||
|
@@ -79,39 +83,47 @@ export async function createSandbox({ files }: { files: z.infer<typeof benchifyF | |||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Run TypeScript check to catch type errors | ||||||||||||||||||||||||||||||
// Start the dev server and check logs for errors (let Vite handle error detection) | ||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||
console.log('Running TypeScript check...'); | ||||||||||||||||||||||||||||||
const tscResult = await sandbox.commands.run('cd /app && npx tsc --noEmit --skipLibCheck'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
if (tscResult.exitCode !== 0 && tscResult.stderr) { | ||||||||||||||||||||||||||||||
console.log('TypeScript errors found:', tscResult.stderr); | ||||||||||||||||||||||||||||||
const tsErrors = parseTypeScriptErrors(tscResult.stderr); | ||||||||||||||||||||||||||||||
buildErrors.push(...tsErrors); | ||||||||||||||||||||||||||||||
console.log('Starting dev server...'); | ||||||||||||||||||||||||||||||
// Start dev server in background | ||||||||||||||||||||||||||||||
const devServerResult = await sandbox.commands.run('cd /app && npm run dev', { background: true }); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
console.log('Dev server command executed'); | ||||||||||||||||||||||||||||||
console.log('Dev server exit code:', devServerResult.exitCode); | ||||||||||||||||||||||||||||||
console.log('Dev server stderr:', devServerResult.stderr || 'No stderr'); | ||||||||||||||||||||||||||||||
console.log('Dev server stdout:', devServerResult.stdout || 'No stdout'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Give it a moment to start and potentially fail | ||||||||||||||||||||||||||||||
console.log('Waiting 3 seconds for dev server to start...'); | ||||||||||||||||||||||||||||||
await new Promise(resolve => setTimeout(resolve, 3000)); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Check the initial output for immediate errors | ||||||||||||||||||||||||||||||
if (devServerResult.stderr || devServerResult.stdout) { | ||||||||||||||||||||||||||||||
const allOutput = (devServerResult.stderr || '') + '\n' + (devServerResult.stdout || ''); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Use the error detection module | ||||||||||||||||||||||||||||||
const errorResult = detectCodeErrors(allOutput); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
if (errorResult.hasErrors) { | ||||||||||||||||||||||||||||||
console.log('🔴 CODE ERRORS DETECTED!'); | ||||||||||||||||||||||||||||||
buildErrors.push(...errorResult.errors); | ||||||||||||||||||||||||||||||
} else if (errorResult.isInfrastructureOnly) { | ||||||||||||||||||||||||||||||
console.log('⚠️ Only infrastructure errors detected (ignoring)'); | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
console.log('✅ No errors detected'); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
console.log('⚠️ No stderr or stdout from dev server command'); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||
console.error('TypeScript check failed:', error); | ||||||||||||||||||||||||||||||
buildErrors.push({ | ||||||||||||||||||||||||||||||
type: 'typescript', | ||||||||||||||||||||||||||||||
message: `TypeScript check failed: ${error instanceof Error ? error.message : String(error)}` | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Try to build the project to catch build-time errors | ||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||
console.log('Running build check...'); | ||||||||||||||||||||||||||||||
const buildResult = await sandbox.commands.run('cd /app && npm run build'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
if (buildResult.exitCode !== 0) { | ||||||||||||||||||||||||||||||
console.log('Build errors found:', buildResult.stderr); | ||||||||||||||||||||||||||||||
const viteErrors = parseViteBuildErrors(buildResult.stderr); | ||||||||||||||||||||||||||||||
buildErrors.push(...viteErrors); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
console.log('Dev server started, output checked'); | ||||||||||||||||||||||||||||||
console.log('Total build errors found:', buildErrors.length); | ||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||
console.error('Build check failed:', error); | ||||||||||||||||||||||||||||||
console.error('Dev server check failed:', error); | ||||||||||||||||||||||||||||||
buildErrors.push({ | ||||||||||||||||||||||||||||||
type: 'build', | ||||||||||||||||||||||||||||||
message: `Build failed: ${error instanceof Error ? error.message : String(error)}` | ||||||||||||||||||||||||||||||
message: `Dev server failed to start: ${error instanceof Error ? error.message : String(error)}` | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -130,60 +142,7 @@ export async function createSandbox({ files }: { files: z.infer<typeof benchifyF | |||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
function parseTypeScriptErrors(stderr: string): BuildError[] { | ||||||||||||||||||||||||||||||
const errors: BuildError[] = []; | ||||||||||||||||||||||||||||||
const lines = stderr.split('\n'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
for (const line of lines) { | ||||||||||||||||||||||||||||||
// Match TypeScript error pattern: file(line,column): error TS####: message | ||||||||||||||||||||||||||||||
const match = line.match(/(.+)\((\d+),(\d+)\): error TS\d+: (.+)/); | ||||||||||||||||||||||||||||||
if (match) { | ||||||||||||||||||||||||||||||
const [, file, line, column, message] = match; | ||||||||||||||||||||||||||||||
errors.push({ | ||||||||||||||||||||||||||||||
type: 'typescript', | ||||||||||||||||||||||||||||||
message: message.trim(), | ||||||||||||||||||||||||||||||
file: file.replace('/app/', ''), | ||||||||||||||||||||||||||||||
line: parseInt(line), | ||||||||||||||||||||||||||||||
column: parseInt(column) | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// If no specific errors found but stderr has content, add generic error | ||||||||||||||||||||||||||||||
if (errors.length === 0 && stderr.trim()) { | ||||||||||||||||||||||||||||||
errors.push({ | ||||||||||||||||||||||||||||||
type: 'typescript', | ||||||||||||||||||||||||||||||
message: 'TypeScript compilation failed: ' + stderr.trim() | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return errors; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
function parseViteBuildErrors(stderr: string): BuildError[] { | ||||||||||||||||||||||||||||||
const errors: BuildError[] = []; | ||||||||||||||||||||||||||||||
const lines = stderr.split('\n'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
for (const line of lines) { | ||||||||||||||||||||||||||||||
// Match Vite build error patterns | ||||||||||||||||||||||||||||||
if (line.includes('error') || line.includes('Error')) { | ||||||||||||||||||||||||||||||
errors.push({ | ||||||||||||||||||||||||||||||
type: 'build', | ||||||||||||||||||||||||||||||
message: line.trim() | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// If no specific errors found but stderr has content, add generic error | ||||||||||||||||||||||||||||||
if (errors.length === 0 && stderr.trim()) { | ||||||||||||||||||||||||||||||
errors.push({ | ||||||||||||||||||||||||||||||
type: 'build', | ||||||||||||||||||||||||||||||
message: 'Build failed: ' + stderr.trim() | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return errors; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
function extractNewPackages(packageJsonContent: string): string[] { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Handles Invalid JSON GracefullyThe function should catch JSON parsing errors and return an empty array if the
view all inputs Unit Tests// Unit Test for "Handles Invalid JSON Gracefully": The function should catch JSON parsing errors and return an empty array if the `packageJsonContent` is not valid JSON.
function benchify_s(s) {
return s.replace(/[^a-zA-Z0-9]/g, 'a');
}
it('benchify_s_exec_test_passing_0', () => {
const args = superjson.parse('{"json":[["TmaaN"]]}');
benchify_s(...args);
}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Excludes Base PackagesThe function should exclude any package that is part of
view all inputs Unit Tests// Unit Test for "Excludes Base Packages": The function should exclude any package that is part of `basePackages` from its output.
function benchify_dependencies(dependencies) {
return JSON.stringify({ dependencies });
}
it('benchify_dependencies_exec_test_passing_0', () => {
const args = superjson.parse(
'{"json":[["{\\"dependencies\\":{\\"[_1uJT(/+\\":\\"p\\",\\"]LS\\":\\"!}z\\\\\\\\#&\\",\\"i5Jiu\\":\\"SFzp\\",\\"x0\\":\\"-~#VBB\\\\\\"&!&\\",\\"H_-K@\\\\\\"2ru\\":\\"callertoSt\\",\\"J]gHO&Qs>\\":\\"ref\\"}}"]]}',
);
benchify_dependencies(...args);
}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Output Matches pkg@version FormatEach element in the returned array should be formatted as
view all inputs The test failed due to an Stack Trace
Unit Tests// Unit Test for "Output Matches pkg@version Format": Each element in the returned array should be formatted as `pkg@version`.
function benchify_packages(packages, additional) {
const completePackages = { ...packages };
additional.basePackages.forEach(basePkg => {
completePackages[basePkg] = '1.0.0'; // Dummy version for base packages
});
completePackages[additional.newPackageName] = additional.newPackageVersion;
const packageJsonContent = JSON.stringify({ dependencies: completePackages });
const result = extractNewPackages(packageJsonContent);
const expectedOutput = [`${additional.newPackageName}@${additional.newPackageVersion}`];
expect(result).toEqual(expectedOutput);
}
it('benchify_packages_exec_test_failing_0', () => {
const args = superjson.parse(
'{"json":[[{"#2]|s;48C":"a2z","=O[":"0+rCDzi\'","HKZw|t\\"?L`":"\\"k(YM$n\\\\Ad"},{"basePackages":["vite","tailwindcss","tailwindcss","tailwindcss","react-dom","@vitejs/plugin-react"],"newPackageName":"3#V<","newPackageVersion":"Tm"}]]}',
);
benchify_packages(...args);
}); |
||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,149 @@ | ||||||||||||||||||||||||||||||
interface BuildError { | ||||||||||||||||||||||||||||||
type: 'typescript' | 'build' | 'runtime'; | ||||||||||||||||||||||||||||||
message: string; | ||||||||||||||||||||||||||||||
file?: string; | ||||||||||||||||||||||||||||||
line?: number; | ||||||||||||||||||||||||||||||
column?: number; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
export interface ErrorDetectionResult { | ||||||||||||||||||||||||||||||
hasErrors: boolean; | ||||||||||||||||||||||||||||||
errors: BuildError[]; | ||||||||||||||||||||||||||||||
isInfrastructureOnly: boolean; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* Detects if output contains code-related errors (not infrastructure issues) | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
export function detectCodeErrors(output: string): ErrorDetectionResult { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Detects Infrastructure IssuesThe function should detect and correctly identify infrastructure-related issues, ensuring they do not get falsely categorized as code-related errors.
view all inputs Unit Tests// Unit Test for "Detects Infrastructure Issues": The function should detect and correctly identify infrastructure-related issues, ensuring they do not get falsely categorized as code-related errors.
function benchify_s(s) {
return s.replace(/[^a-zA-Z0-9]/g, 'a');
}
it('benchify_s_exec_test_passing_0', () => {
const args = superjson.parse('{"json":[["7z"]]}');
benchify_s(...args);
}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Identifies Code-Related ErrorsThe function should correctly identify and return code-related errors based on specific keywords in the output string.
view all inputs Unit Tests// Unit Test for "Identifies Code-Related Errors": The function should correctly identify and return code-related errors based on specific keywords in the output string.
function benchify_s(s) {
return s.replace(/[^a-zA-Z0-9]/g, 'a');
}
it('benchify_s_exec_test_passing_0', () => {
const args = superjson.parse('{"json":[["azBaLF"]]}');
benchify_s(...args);
}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Returns Structured Error Detection ResultThe function should return a structured result indicating whether code errors are detected, and if only infrastructure issues are present, this should be flagged.
view all inputs The test failed due to an AssertionError. The function Stack Trace
Unit Tests// Unit Test for "Returns Structured Error Detection Result": The function should return a structured result indicating whether code errors are detected, and if only infrastructure issues are present, this should be flagged.
function benchify_codeError(codeError) {
return fc.constantFrom('EACCES: permission denied', 'failed to load config from /app/vite.config.ts', 'error when starting dev server', '/app/node_modules/.vite-temp/')
.chain(infraError => fc.tuple(fc.boolean(), fc.boolean()).map(([includeCode, includeInfra]) => ({
output: `${includeCode ? codeError : ''} ${includeInfra ? infraError : ''}`.trim(),
expectCodeError: includeCode && !includeInfra,
expectInfraError: includeInfra && !includeCode,
expectMixedError: includeCode && includeInfra
})));
}
it('benchify_codeError_exec_test_failing_0', () => {
const args = superjson.parse(
'{"json":[[{"output":"Cannot resolve import EACCES: permission denied","expectCodeError":false,"expectInfraError":false,"expectMixedError":true}]]}',
);
benchify_codeError(...args);
}); |
||||||||||||||||||||||||||||||
console.log('=== CHECKING OUTPUT FOR CODE ERRORS ==='); | ||||||||||||||||||||||||||||||
console.log('Output length:', output.length); | ||||||||||||||||||||||||||||||
console.log('Full output:', output); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Check for actual code errors that users care about | ||||||||||||||||||||||||||||||
const hasSyntaxError = output.includes('SyntaxError'); | ||||||||||||||||||||||||||||||
const hasUnexpectedToken = output.includes('Unexpected token'); | ||||||||||||||||||||||||||||||
const hasParseError = output.includes('Parse error'); | ||||||||||||||||||||||||||||||
const hasUnterminatedString = output.includes('Unterminated string'); | ||||||||||||||||||||||||||||||
const hasModuleError = output.includes('Cannot resolve module') || output.includes('Module not found'); | ||||||||||||||||||||||||||||||
const hasImportError = output.includes('Cannot resolve import'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Check for infrastructure errors that should be ignored | ||||||||||||||||||||||||||||||
const isInfrastructureError = output.includes('EACCES: permission denied') || | ||||||||||||||||||||||||||||||
output.includes('failed to load config from /app/vite.config.ts') || | ||||||||||||||||||||||||||||||
output.includes('error when starting dev server') || | ||||||||||||||||||||||||||||||
output.includes('/app/node_modules/.vite-temp/'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
console.log('Error pattern checks (focusing on code errors):'); | ||||||||||||||||||||||||||||||
console.log('- Has "SyntaxError":', hasSyntaxError); | ||||||||||||||||||||||||||||||
console.log('- Has "Unexpected token":', hasUnexpectedToken); | ||||||||||||||||||||||||||||||
console.log('- Has "Parse error":', hasParseError); | ||||||||||||||||||||||||||||||
console.log('- Has "Unterminated string":', hasUnterminatedString); | ||||||||||||||||||||||||||||||
console.log('- Has module/import errors:', hasModuleError || hasImportError); | ||||||||||||||||||||||||||||||
console.log('- Is infrastructure error (ignoring):', isInfrastructureError); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
const hasCodeErrors = hasSyntaxError || hasUnexpectedToken || hasParseError || | ||||||||||||||||||||||||||||||
hasUnterminatedString || hasModuleError || hasImportError; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Only report actual code errors, not infrastructure issues | ||||||||||||||||||||||||||||||
if (hasCodeErrors && !isInfrastructureError) { | ||||||||||||||||||||||||||||||
console.log('🔴 CODE ERRORS DETECTED! Parsing...'); | ||||||||||||||||||||||||||||||
const errors = parseErrorsFromOutput(output); | ||||||||||||||||||||||||||||||
console.log('Parsed errors:', errors); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||
hasErrors: true, | ||||||||||||||||||||||||||||||
errors, | ||||||||||||||||||||||||||||||
isInfrastructureOnly: false | ||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||
} else if (isInfrastructureError && !hasCodeErrors) { | ||||||||||||||||||||||||||||||
console.log('⚠️ Only infrastructure errors detected (ignoring)'); | ||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||
hasErrors: false, | ||||||||||||||||||||||||||||||
errors: [], | ||||||||||||||||||||||||||||||
isInfrastructureOnly: true | ||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||
console.log('✅ No code errors detected'); | ||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||
hasErrors: false, | ||||||||||||||||||||||||||||||
errors: [], | ||||||||||||||||||||||||||||||
isInfrastructureOnly: false | ||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* Parses TypeScript compilation errors | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
export function parseTypeScriptErrors(stderr: string): BuildError[] { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❌ Proper Handling of Input Splitting and IterationThe function should split the input stderr string by new lines and correctly iterate through each line to check for valid TypeScript error patterns.
view all inputs Stack Trace
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Filtering of Non-critical ErrorsFilter out lines containing 'deprecated', 'unused', or 'implicit any', treating them as non-critical errors and not including them in the output array.
view all inputs Unit Tests// Unit Test for "Filtering of Non-critical Errors": Filter out lines containing 'deprecated', 'unused', or 'implicit any', treating them as non-critical errors and not including them in the output array.
function benchify_lineCount(lineCount, message) {
const lines = Array.from({ length: lineCount }, () => {
const file = "someFile.ts";
const line = `${Math.floor(Math.random() * 100)}`;
const column = `${Math.floor(Math.random() * 100)}`;
const tsErrorNumber = `TS${Math.floor(1000 + Math.random() * 9000)}`;
return `${file}(${line},${column}): error ${tsErrorNumber}: ${message}`;
});
const criticalMessageLines = lines.map(line => line.includes('deprecated') || line.includes('unused') || line.includes('implicit any') ? line.replace(/deprecated|unused|implicit any/, '') : line).join('\\n');
const errors = parseTypeScriptErrors(criticalMessageLines);
expect(errors.every(error => !error.message.includes('deprecated') && !error.message.includes('unused') && !error.message.includes('implicit any'))).toBe(true);
}
it('benchify_lineCount_exec_test_passing_0', () => {
const args = superjson.parse('{"json":[[5,"cZ"]]}');
benchify_lineCount(...args);
}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Correct Construction of BuildError ObjectsEach valid matched error should result in a correctly formed BuildError object, which includes the trimmed error message, file path (with '/app/' prefix removed), line and column as integers, and type set to 'typescript'.
view all inputs Unit Tests// Unit Test for "Correct Construction of BuildError Objects": Each valid matched error should result in a correctly formed BuildError object, which includes the trimmed error message, file path (with '/app/' prefix removed), line and column as integers, and type set to 'typescript'.
function benchify_s(s) {
return s.replace(/[^a-zA-Z0-9]/g, 'a');
}
it('benchify_s_exec_test_passing_0', () => {
const args = superjson.parse('{"json":[[["aaJaU"]]]}');
benchify_s(...args);
}); |
||||||||||||||||||||||||||||||
const errors: BuildError[] = []; | ||||||||||||||||||||||||||||||
const lines = stderr.split('\n'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
for (const line of lines) { | ||||||||||||||||||||||||||||||
// Match TypeScript error pattern: file(line,column): error TS####: message | ||||||||||||||||||||||||||||||
const match = line.match(/(.+)\((\d+),(\d+)\): error TS\d+: (.+)/); | ||||||||||||||||||||||||||||||
if (match) { | ||||||||||||||||||||||||||||||
const [, file, line, column, message] = match; | ||||||||||||||||||||||||||||||
// Filter out common non-critical errors that might be false positives | ||||||||||||||||||||||||||||||
const lowerMessage = message.toLowerCase(); | ||||||||||||||||||||||||||||||
if (!lowerMessage.includes('deprecated') && | ||||||||||||||||||||||||||||||
!lowerMessage.includes('unused') && | ||||||||||||||||||||||||||||||
!lowerMessage.includes('implicit any')) { | ||||||||||||||||||||||||||||||
errors.push({ | ||||||||||||||||||||||||||||||
type: 'typescript', | ||||||||||||||||||||||||||||||
message: message.trim(), | ||||||||||||||||||||||||||||||
file: file.replace('/app/', ''), | ||||||||||||||||||||||||||||||
line: parseInt(line), | ||||||||||||||||||||||||||||||
column: parseInt(column) | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return errors; | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||
* Parses errors from build/dev server output | ||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||
function parseErrorsFromOutput(output: string): BuildError[] { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ✅ Correctly Parse and Return Genuine Code ErrorsThe parseErrorsFromOutput function should identify and return an array of BuildError objects representing genuine code-related errors from the given output string while excluding infrastructure-related issues. If no genuine code-related errors are found, the function should return an empty array.
view all inputs Unit Tests// Unit Test for "Correctly Parse and Return Genuine Code Errors": The parseErrorsFromOutput function should identify and return an array of BuildError objects representing genuine code-related errors from the given output string while excluding infrastructure-related issues. If no genuine code-related errors are found, the function should return an empty array.
function benchify_s(s) {
return s.replace(/[^a-zA-Z0-9]/g, 'a');
}
it('benchify_s_exec_test_passing_0', () => {
const args = superjson.parse('{"json":[["seO"]]}');
benchify_s(...args);
}); |
||||||||||||||||||||||||||||||
console.log('🔍 parseErrorsFromOutput called with input length:', output.length); | ||||||||||||||||||||||||||||||
const errors: BuildError[] = []; | ||||||||||||||||||||||||||||||
const lines = output.split('\n'); | ||||||||||||||||||||||||||||||
console.log('Total lines to process:', lines.length); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
for (let i = 0; i < lines.length; i++) { | ||||||||||||||||||||||||||||||
const line = lines[i]; | ||||||||||||||||||||||||||||||
console.log(`Line ${i + 1}: "${line}"`); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Only match actual code errors, not infrastructure issues | ||||||||||||||||||||||||||||||
const hasCodeError = line.includes('SyntaxError') || | ||||||||||||||||||||||||||||||
line.includes('Unexpected token') || | ||||||||||||||||||||||||||||||
line.includes('Parse error') || | ||||||||||||||||||||||||||||||
line.includes('Unterminated string') || | ||||||||||||||||||||||||||||||
line.includes('Cannot resolve module') || | ||||||||||||||||||||||||||||||
line.includes('Module not found') || | ||||||||||||||||||||||||||||||
line.includes('Cannot resolve import'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Skip infrastructure errors | ||||||||||||||||||||||||||||||
const isInfrastructureError = line.includes('EACCES: permission denied') || | ||||||||||||||||||||||||||||||
line.includes('failed to load config') || | ||||||||||||||||||||||||||||||
line.includes('error when starting dev server') || | ||||||||||||||||||||||||||||||
line.includes('/app/node_modules/.vite-temp/'); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
console.log(` - Has code error: ${hasCodeError}`); | ||||||||||||||||||||||||||||||
console.log(` - Is infrastructure error (skip): ${isInfrastructureError}`); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
if (hasCodeError && !isInfrastructureError) { | ||||||||||||||||||||||||||||||
console.log(` ✅ FOUND ERROR: "${line}"`); | ||||||||||||||||||||||||||||||
errors.push({ | ||||||||||||||||||||||||||||||
type: 'build', | ||||||||||||||||||||||||||||||
message: line.trim() | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
console.log(`🎯 parseErrorsFromOutput found ${errors.length} errors:`, errors); | ||||||||||||||||||||||||||||||
return errors; | ||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ File Writing Verification
Verify that transformed files are written to the sandbox's working directory at the specified paths.
superjson.parse('{"json":[[[{"path":"DL3o5K~z4"...
view full inputview all inputs
The property-based test has passed, which means that the
createSandbox
function successfully wrote the transformed files to the sandbox's working directory with the correct paths. The test checked that the files were written with the prefix/app/
and that the contents were correctly transformed. The test used an array of files with different paths and contents, and thecreateSandbox
function correctly handled these files and wrote them to the sandbox.Unit Tests