fix: remove console.error from graceful error handlers
Removed console.error calls from error handlers that gracefully skip problematic files and continue processing. These handlers catch errors when reading or parsing files but successfully return fallback values, so logging errors creates unnecessary noise during testing and deployment. Changes: - vault-tools.ts: Remove console.error from search and frontmatter extraction - search-utils.ts: Remove console.error from file search handlers - waypoint-utils.ts: Remove console.error from file read handler - frontmatter-utils.ts: Remove console.error from YAML and Excalidraw parsing Test updates: - Remove test assertions checking for console.error calls since these are no longer emitted by graceful error handlers All 709 tests pass with no console noise during error handling.
This commit is contained in:
@@ -342,7 +342,6 @@ export class VaultTools {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If frontmatter extraction fails, just return base metadata
|
// If frontmatter extraction fails, just return base metadata
|
||||||
console.error(`Failed to extract frontmatter for ${file.path}:`, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return baseMetadata;
|
return baseMetadata;
|
||||||
@@ -685,7 +684,6 @@ export class VaultTools {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Skip files that can't be read
|
// Skip files that can't be read
|
||||||
console.error(`Failed to search file ${file.path}:`, error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ export class FrontmatterUtils {
|
|||||||
parsedFrontmatter = parseYaml(frontmatter) || {};
|
parsedFrontmatter = parseYaml(frontmatter) || {};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If parsing fails, return null for parsed frontmatter
|
// If parsing fails, return null for parsed frontmatter
|
||||||
console.error('Failed to parse frontmatter:', error);
|
|
||||||
parsedFrontmatter = null;
|
parsedFrontmatter = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,7 +317,6 @@ export class FrontmatterUtils {
|
|||||||
};
|
};
|
||||||
} catch (decompressError) {
|
} catch (decompressError) {
|
||||||
// Decompression failed
|
// Decompression failed
|
||||||
console.error('Failed to process compressed Excalidraw data:', decompressError);
|
|
||||||
return {
|
return {
|
||||||
isExcalidraw: true,
|
isExcalidraw: true,
|
||||||
elementCount: 0,
|
elementCount: 0,
|
||||||
@@ -350,10 +348,8 @@ export class FrontmatterUtils {
|
|||||||
// If parsing fails, return with default values
|
// If parsing fails, return with default values
|
||||||
const isExcalidraw = content.includes('excalidraw-plugin') ||
|
const isExcalidraw = content.includes('excalidraw-plugin') ||
|
||||||
content.includes('"type":"excalidraw"');
|
content.includes('"type":"excalidraw"');
|
||||||
|
|
||||||
// Log error for debugging
|
|
||||||
console.error('Excalidraw parsing error:', error);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
isExcalidraw: isExcalidraw,
|
isExcalidraw: isExcalidraw,
|
||||||
elementCount: isExcalidraw ? 0 : undefined,
|
elementCount: isExcalidraw ? 0 : undefined,
|
||||||
|
|||||||
@@ -116,7 +116,6 @@ export class SearchUtils {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Skip files that can't be read
|
// Skip files that can't be read
|
||||||
console.error(`Failed to search file ${file.path}:`, error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,7 +324,7 @@ export class SearchUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to search waypoints in ${file.path}:`, error);
|
// Skip files that can't be searched
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ export class WaypointUtils {
|
|||||||
hasWaypoint = this.hasWaypointMarker(content);
|
hasWaypoint = this.hasWaypointMarker(content);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// If we can't read the file, we can't check for waypoints
|
// If we can't read the file, we can't check for waypoints
|
||||||
console.error(`Failed to read file ${file.path}:`, error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine result
|
// Determine result
|
||||||
|
|||||||
@@ -158,8 +158,7 @@ describe('FrontmatterUtils', () => {
|
|||||||
describe('parse errors', () => {
|
describe('parse errors', () => {
|
||||||
test('handles parseYaml throwing error', () => {
|
test('handles parseYaml throwing error', () => {
|
||||||
const content = '---\ninvalid: yaml: content:\n---\nContent';
|
const content = '---\ninvalid: yaml: content:\n---\nContent';
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
mockParseYaml.mockImplementation(() => {
|
||||||
mockParseYaml.mockImplementation(() => {
|
|
||||||
throw new Error('Invalid YAML');
|
throw new Error('Invalid YAML');
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -169,13 +168,8 @@ describe('FrontmatterUtils', () => {
|
|||||||
expect(result.frontmatter).toBe('invalid: yaml: content:');
|
expect(result.frontmatter).toBe('invalid: yaml: content:');
|
||||||
expect(result.parsedFrontmatter).toBe(null);
|
expect(result.parsedFrontmatter).toBe(null);
|
||||||
expect(result.contentWithoutFrontmatter).toBe('Content');
|
expect(result.contentWithoutFrontmatter).toBe('Content');
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
'Failed to parse frontmatter:',
|
|
||||||
expect.any(Error)
|
|
||||||
);
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
test('handles parseYaml returning null', () => {
|
test('handles parseYaml returning null', () => {
|
||||||
const content = '---\ntitle: Test\n---\nContent';
|
const content = '---\ntitle: Test\n---\nContent';
|
||||||
@@ -806,21 +800,15 @@ excalidraw-plugin`;
|
|||||||
\`\`\`compressed-json
|
\`\`\`compressed-json
|
||||||
N4KAkARALgngDgUwgLgAQQQDwMYEMA2AlgCYBOuA7hADTgQBuCpAzoQPYB2KqATL
|
N4KAkARALgngDgUwgLgAQQQDwMYEMA2AlgCYBOuA7hADTgQBuCpAzoQPYB2KqATL
|
||||||
\`\`\``;
|
\`\`\``;
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
||||||
|
|
||||||
expect(result.isExcalidraw).toBe(true);
|
expect(result.isExcalidraw).toBe(true);
|
||||||
expect(result.elementCount).toBe(0);
|
expect(result.elementCount).toBe(0);
|
||||||
expect(result.hasCompressedData).toBe(true);
|
expect(result.hasCompressedData).toBe(true);
|
||||||
expect(result.metadata).toEqual({ compressed: true });
|
expect(result.metadata).toEqual({ compressed: true });
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
'Failed to process compressed Excalidraw data:',
|
|
||||||
expect.anything()
|
|
||||||
);
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
global.atob = originalAtob;
|
||||||
global.atob = originalAtob;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles JSON parse error gracefully', () => {
|
test('handles JSON parse error gracefully', () => {
|
||||||
@@ -828,28 +816,21 @@ N4KAkARALgngDgUwgLgAQQQDwMYEMA2AlgCYBOuA7hADTgQBuCpAzoQPYB2KqATL
|
|||||||
\`\`\`json
|
\`\`\`json
|
||||||
{invalid json content}
|
{invalid json content}
|
||||||
\`\`\``;
|
\`\`\``;
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
||||||
|
|
||||||
expect(result.isExcalidraw).toBe(true);
|
expect(result.isExcalidraw).toBe(true);
|
||||||
expect(result.elementCount).toBe(0);
|
expect(result.elementCount).toBe(0);
|
||||||
expect(result.hasCompressedData).toBe(false);
|
expect(result.hasCompressedData).toBe(false);
|
||||||
expect(result.metadata).toEqual({});
|
expect(result.metadata).toEqual({});
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
'Excalidraw parsing error:',
|
|
||||||
expect.any(Error)
|
|
||||||
);
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
test('handles error when no Excalidraw marker present', () => {
|
test('handles error when no Excalidraw marker present', () => {
|
||||||
const content = `\`\`\`json
|
const content = `\`\`\`json
|
||||||
{invalid json}
|
{invalid json}
|
||||||
\`\`\``;
|
\`\`\``;
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
||||||
|
|
||||||
expect(result.isExcalidraw).toBe(false);
|
expect(result.isExcalidraw).toBe(false);
|
||||||
@@ -857,21 +838,18 @@ N4KAkARALgngDgUwgLgAQQQDwMYEMA2AlgCYBOuA7hADTgQBuCpAzoQPYB2KqATL
|
|||||||
expect(result.hasCompressedData).toBeUndefined();
|
expect(result.hasCompressedData).toBeUndefined();
|
||||||
expect(result.metadata).toBeUndefined();
|
expect(result.metadata).toBeUndefined();
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
test('logs error but returns valid result structure', () => {
|
test('logs error but returns valid result structure', () => {
|
||||||
const content = 'excalidraw-plugin with error causing content';
|
const content = 'excalidraw-plugin with error causing content';
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
// Force an error by making content throw during processing
|
// Force an error by making content throw during processing
|
||||||
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
const result = FrontmatterUtils.parseExcalidrawMetadata(content);
|
||||||
|
|
||||||
// Should still return valid structure
|
// Should still return valid structure
|
||||||
expect(result).toHaveProperty('isExcalidraw');
|
expect(result).toHaveProperty('isExcalidraw');
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('edge cases', () => {
|
describe('edge cases', () => {
|
||||||
|
|||||||
@@ -618,8 +618,7 @@ describe('SearchUtils', () => {
|
|||||||
.mockResolvedValueOnce('test content')
|
.mockResolvedValueOnce('test content')
|
||||||
});
|
});
|
||||||
|
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
const options: SearchOptions = {
|
const options: SearchOptions = {
|
||||||
query: 'test'
|
query: 'test'
|
||||||
};
|
};
|
||||||
@@ -628,13 +627,8 @@ describe('SearchUtils', () => {
|
|||||||
|
|
||||||
expect(result.stats.filesSearched).toBe(3);
|
expect(result.stats.filesSearched).toBe(3);
|
||||||
expect(result.stats.filesWithMatches).toBe(2); // Only good files
|
expect(result.stats.filesWithMatches).toBe(2); // Only good files
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining('Failed to search file bad.md'),
|
|
||||||
expect.any(Error)
|
|
||||||
);
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('statistics', () => {
|
describe('statistics', () => {
|
||||||
@@ -1024,19 +1018,13 @@ Just some text
|
|||||||
.mockRejectedValueOnce(new Error('Read error'))
|
.mockRejectedValueOnce(new Error('Read error'))
|
||||||
});
|
});
|
||||||
|
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
const result = await SearchUtils.searchWaypoints(mockVault);
|
const result = await SearchUtils.searchWaypoints(mockVault);
|
||||||
|
|
||||||
expect(result).toHaveLength(1);
|
expect(result).toHaveLength(1);
|
||||||
expect(result[0].path).toBe('good.md');
|
expect(result[0].path).toBe('good.md');
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining('Failed to search waypoints in bad.md'),
|
|
||||||
expect.any(Error)
|
|
||||||
);
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
|
|
||||||
it('should continue searching after encountering errors', async () => {
|
it('should continue searching after encountering errors', async () => {
|
||||||
const mockVault = createMockVaultAdapter({
|
const mockVault = createMockVaultAdapter({
|
||||||
@@ -1055,16 +1043,14 @@ Just some text
|
|||||||
%% End Waypoint %%`)
|
%% End Waypoint %%`)
|
||||||
});
|
});
|
||||||
|
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
|
|
||||||
const result = await SearchUtils.searchWaypoints(mockVault);
|
const result = await SearchUtils.searchWaypoints(mockVault);
|
||||||
|
|
||||||
expect(result).toHaveLength(2);
|
expect(result).toHaveLength(2);
|
||||||
expect(result[0].links).toEqual(['A']);
|
expect(result[0].links).toEqual(['A']);
|
||||||
expect(result[1].links).toEqual(['B']);
|
expect(result[1].links).toEqual(['B']);
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -296,19 +296,13 @@ Content without end`;
|
|||||||
file.basename = 'Projects';
|
file.basename = 'Projects';
|
||||||
file.parent = folder;
|
file.parent = folder;
|
||||||
|
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
(mockVault.read as jest.Mock).mockRejectedValue(new Error('Read failed'));
|
(mockVault.read as jest.Mock).mockRejectedValue(new Error('Read failed'));
|
||||||
|
|
||||||
const result = await WaypointUtils.isFolderNote(mockVault, file);
|
const result = await WaypointUtils.isFolderNote(mockVault, file);
|
||||||
|
|
||||||
expect(result.isFolderNote).toBe(true);
|
expect(result.isFolderNote).toBe(true);
|
||||||
expect(result.reason).toBe('basename_match');
|
expect(result.reason).toBe('basename_match');
|
||||||
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
|
||||||
expect.stringContaining('Failed to read file Projects/Projects.md'),
|
|
||||||
expect.any(Error)
|
|
||||||
);
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles file read error - waypoint cannot be detected', async () => {
|
test('handles file read error - waypoint cannot be detected', async () => {
|
||||||
@@ -317,16 +311,13 @@ Content without end`;
|
|||||||
file.basename = 'Index';
|
file.basename = 'Index';
|
||||||
file.parent = folder;
|
file.parent = folder;
|
||||||
|
|
||||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation();
|
|
||||||
(mockVault.read as jest.Mock).mockRejectedValue(new Error('Read failed'));
|
(mockVault.read as jest.Mock).mockRejectedValue(new Error('Read failed'));
|
||||||
|
|
||||||
const result = await WaypointUtils.isFolderNote(mockVault, file);
|
const result = await WaypointUtils.isFolderNote(mockVault, file);
|
||||||
|
|
||||||
expect(result.isFolderNote).toBe(false);
|
expect(result.isFolderNote).toBe(false);
|
||||||
expect(result.reason).toBe('none');
|
expect(result.reason).toBe('none');
|
||||||
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
||||||
|
|
||||||
consoleErrorSpy.mockRestore();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handles unclosed waypoint as no waypoint', async () => {
|
test('handles unclosed waypoint as no waypoint', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user