fix: add error handling to repository methods per code review

- Added try-catch blocks to getNodePropertyDefaults and getDefaultOperationForResource
- Validates displayOptions structure before accessing to prevent crashes
- Returns safe defaults (empty object or undefined) on errors
- Ensures validation continues even with malformed node data
- Addresses code review feedback about error boundaries
This commit is contained in:
czlonkowski
2025-09-29 18:22:58 +02:00
parent 9fa1c44149
commit 2896e393d3

View File

@@ -382,52 +382,71 @@ export class NodeRepository {
* Get default values for node properties * Get default values for node properties
*/ */
getNodePropertyDefaults(nodeType: string): Record<string, any> { getNodePropertyDefaults(nodeType: string): Record<string, any> {
const node = this.getNode(nodeType); try {
if (!node || !node.properties) return {}; const node = this.getNode(nodeType);
if (!node || !node.properties) return {};
const defaults: Record<string, any> = {}; const defaults: Record<string, any> = {};
for (const prop of node.properties) { for (const prop of node.properties) {
if (prop.default !== undefined) { if (prop.name && prop.default !== undefined) {
defaults[prop.name] = prop.default; defaults[prop.name] = prop.default;
}
} }
}
return defaults; return defaults;
} catch (error) {
// Log error and return empty defaults rather than throwing
console.error(`Error getting property defaults for ${nodeType}:`, error);
return {};
}
} }
/** /**
* Get the default operation for a specific resource * Get the default operation for a specific resource
*/ */
getDefaultOperationForResource(nodeType: string, resource?: string): string | undefined { getDefaultOperationForResource(nodeType: string, resource?: string): string | undefined {
const node = this.getNode(nodeType); try {
if (!node || !node.properties) return undefined; const node = this.getNode(nodeType);
if (!node || !node.properties) return undefined;
// Find operation property that's visible for this resource // Find operation property that's visible for this resource
for (const prop of node.properties) { for (const prop of node.properties) {
if (prop.name === 'operation') { if (prop.name === 'operation') {
// If there's a resource dependency, check if it matches // If there's a resource dependency, check if it matches
if (resource && prop.displayOptions?.show?.resource) { if (resource && prop.displayOptions?.show?.resource) {
const allowedResources = Array.isArray(prop.displayOptions.show.resource) // Validate displayOptions structure
? prop.displayOptions.show.resource const resourceDep = prop.displayOptions.show.resource;
: [prop.displayOptions.show.resource]; if (!Array.isArray(resourceDep) && typeof resourceDep !== 'string') {
continue; // Skip malformed displayOptions
}
if (!allowedResources.includes(resource)) { const allowedResources = Array.isArray(resourceDep)
continue; // This operation property doesn't apply to our resource ? resourceDep
: [resourceDep];
if (!allowedResources.includes(resource)) {
continue; // This operation property doesn't apply to our resource
}
}
// Return the default value if it exists
if (prop.default !== undefined) {
return prop.default;
}
// If no default but has options, return the first option's value
if (prop.options && Array.isArray(prop.options) && prop.options.length > 0) {
const firstOption = prop.options[0];
return typeof firstOption === 'string' ? firstOption : firstOption.value;
} }
} }
// Return the default value if it exists
if (prop.default !== undefined) {
return prop.default;
}
// If no default but has options, return the first option's value
if (prop.options && prop.options.length > 0) {
const firstOption = prop.options[0];
return typeof firstOption === 'string' ? firstOption : firstOption.value;
}
} }
} catch (error) {
// Log error and return undefined rather than throwing
// This ensures validation continues even with malformed node data
console.error(`Error getting default operation for ${nodeType}:`, error);
return undefined;
} }
return undefined; return undefined;