fix: resolve custom threshold configuration errors

- Add validation to prevent API calls with missing nodeId/vmid parameters
- Implement proper guest selector initialization for edit modal
- Add server-side error handlers to return JSON instead of HTML for API routes
- Include debug logging for threshold configuration troubleshooting
- Ensure dropdown selection properly populates all required hidden fields

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
courtmanr@gmail.com
2025-05-31 11:48:39 +01:00
parent eba6074fd7
commit 34b66f166a
2 changed files with 51 additions and 0 deletions
+25
View File
@@ -723,6 +723,31 @@ app.get('/api/diagnostics', async (req, res) => {
}
});
// Global error handler for unhandled API errors
app.use((err, req, res, next) => {
console.error('Unhandled API error:', err);
// Ensure we always return JSON for API routes
if (req.url.startsWith('/api/')) {
return res.status(500).json({
success: false,
error: 'Internal server error',
message: err.message
});
}
// For non-API routes, return HTML error
res.status(500).send('Internal Server Error');
});
// 404 handler for API routes
app.use('/api/*', (req, res) => {
res.status(404).json({
success: false,
error: 'API endpoint not found'
});
});
// --- WebSocket Setup ---
const io = new Server(server, {
// Optional: Configure CORS for Socket.IO if needed, separate from Express CORS
+26
View File
@@ -1440,6 +1440,16 @@ PulseApp.ui.settings = (() => {
const nodeField = document.getElementById('threshold-node');
const vmidField = document.getElementById('threshold-vmid');
// If editing existing threshold, select the correct guest in dropdown
if (endpointId && vmid) {
const selectValue = `${endpointId}:${vmid}`;
guestSelector.value = selectValue;
// Trigger change event to populate hidden fields properly
const changeEvent = new Event('change');
guestSelector.dispatchEvent(changeEvent);
}
guestSelector.addEventListener('change', (e) => {
if (e.target.value) {
const [selectedEndpoint, selectedVmid] = e.target.value.split(':');
@@ -1449,6 +1459,14 @@ PulseApp.ui.settings = (() => {
// Find the current node for this VM (for display purposes)
const selectedGuest = allGuests.find(g => g.endpointId === selectedEndpoint && g.id === selectedVmid);
nodeField.value = selectedGuest ? selectedGuest.node : '';
// Debug logging
console.log('[Settings] Guest selector changed:', {
selectedEndpoint,
selectedVmid,
selectedGuest,
nodeValue: selectedGuest ? selectedGuest.node : 'MISSING'
});
} else {
endpointField.value = '';
nodeField.value = '';
@@ -1496,6 +1514,14 @@ PulseApp.ui.settings = (() => {
const nodeId = document.getElementById('threshold-node').value;
const vmid = document.getElementById('threshold-vmid').value;
// Validate required fields
if (!endpointId || !nodeId || !vmid) {
alert('Please select a VM/LXC from the dropdown first.');
return;
}
console.log('[Settings] Saving thresholds for:', { endpointId, nodeId, vmid });
try {
const method = existingThresholds ? 'PUT' : 'POST';
const response = await fetch(`/api/thresholds/${endpointId}/${nodeId}/${vmid}`, {