Skip to content

fix(api): replace generic 500 errors with specific kubernetes api errors#265

Open
hemantch01 wants to merge 1 commit into
volcano-sh:mainfrom
hemantch01:fix/improve-error-messages
Open

fix(api): replace generic 500 errors with specific kubernetes api errors#265
hemantch01 wants to merge 1 commit into
volcano-sh:mainfrom
hemantch01:fix/improve-error-messages

Conversation

@hemantch01
Copy link
Copy Markdown

What this PR does

Replaces the generic 500 Internal Server Error responses in the backend API with dynamic status codes that capture the actual Kubernetes API errors. Users will now receive specific, actionable error messages (like 409 Conflict, 403 Forbidden, 404 Not Found, and 422 Unprocessable Entity) when a resource creation or update fails, immediately improving troubleshooting in the dashboard.

Changes

  • backend/src/server.js: Updated the catch blocks for POST and PATCH routes (/api/pods, /api/jobs, /api/queues) to parse the Kubernetes API client error and return the correct HTTP status code and message.

…date failures

Signed-off-by: hemantch01 <hemantchaudhary905@gmail.com>
@volcano-sh-bot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign monokaix for approval. For more information see the Kubernetes Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances error handling across several API endpoints for jobs, queues, and pods by replacing generic 500 errors with specific status codes and descriptive messages based on Kubernetes responses. The feedback suggests refactoring the repeated if-else logic into a more declarative object-based mapping to improve code readability and maintainability across all modified catch blocks.

Comment thread backend/src/server.js
Comment on lines +644 to +656
let msg;

if (statusCode === 404) {
msg = `Job '${req.params.name}' not found in namespace '${req.params.namespace}'.`;
} else if (statusCode === 409) {
msg = "Conflict: the job was modified by another process. Please refresh and try again.";
} else if (statusCode === 403) {
msg = "Permission denied. Check your cluster RBAC permissions.";
} else {
msg = k8sMessage || "Failed to update job";
}

res.status(statusCode).json({ error: msg });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This if-else if chain can be simplified by using an object to map status codes to their corresponding error messages. This approach is more declarative, readable, and easier to maintain.

        const errorMessages = {
            404: `Job '${req.params.name}' not found in namespace '${req.params.namespace}'.`,
            409: "Conflict: the job was modified by another process. Please refresh and try again.",
            403: "Permission denied. Check your cluster RBAC permissions.",
        };
        const msg = errorMessages[statusCode] || k8sMessage || "Failed to update job";
        res.status(statusCode).json({ error: msg });

Comment thread backend/src/server.js
Comment on lines +686 to +698
let msg;

if (statusCode === 404) {
msg = `Queue '${req.params.name}' not found.`;
} else if (statusCode === 409) {
msg = "Conflict: the queue was modified by another process. Please refresh and try again.";
} else if (statusCode === 403) {
msg = "Permission denied. Check your cluster RBAC permissions.";
} else {
msg = k8sMessage || "Failed to update queue";
}

res.status(statusCode).json({ error: msg });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Similar to the other error handlers, this if-else if chain can be refactored using an object for mapping status codes to messages. This improves code clarity and maintainability by reducing boilerplate.

        const errorMessages = {
            404: `Queue '${req.params.name}' not found.`,
            409: "Conflict: the queue was modified by another process. Please refresh and try again.",
            403: "Permission denied. Check your cluster RBAC permissions.",
        };
        const msg = errorMessages[statusCode] || k8sMessage || "Failed to update queue";
        res.status(statusCode).json({ error: msg });

Comment thread backend/src/server.js
Comment on lines +791 to +804
let msg;

if (statusCode === 409) {
const podName = podManifest?.metadata?.name || "unknown";
msg = `A pod named '${podName}' already exists in this namespace.`;
} else if (statusCode === 403) {
msg = "Permission denied. Check your cluster RBAC permissions.";
} else if (statusCode === 422) {
msg = "Invalid pod specification: " + k8sMessage;
} else {
msg = k8sMessage || "Failed to create pod";
}
res.status(500).json({ error: msg });

res.status(statusCode).json({ error: msg });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This if-else if block can be made more concise and readable by using an object to map status codes to error messages. This also makes it easier to manage error messages.

        const errorMessages = {
            409: `A pod named '${podManifest?.metadata?.name || "unknown"}' already exists in this namespace.`,
            403: "Permission denied. Check your cluster RBAC permissions.",
            422: `Invalid pod specification: ${k8sMessage}`,
        };
        const msg = errorMessages[statusCode] || k8sMessage || "Failed to create pod";
        res.status(statusCode).json({ error: msg });

Comment thread backend/src/server.js
Comment on lines +838 to +851
let msg;

if (statusCode === 409) {
const jobName = jobManifest?.metadata?.name || "unknown";
msg = `A job named '${jobName}' already exists in this namespace.`;
} else if (statusCode === 403) {
msg = "Permission denied. Check your cluster RBAC permissions.";
} else if (statusCode === 422) {
msg = "Invalid job specification: " + k8sMessage;
} else {
msg = k8sMessage || "Failed to create job";
}

res.status(statusCode).json({ error: msg });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To improve readability and maintainability, you can replace this if-else if structure with an object that maps status codes to their respective error messages. This pattern is cleaner and less verbose.

        const errorMessages = {
            409: `A job named '${jobManifest?.metadata?.name || "unknown"}' already exists in this namespace.`,
            403: "Permission denied. Check your cluster RBAC permissions.",
            422: `Invalid job specification: ${k8sMessage}`,
        };
        const msg = errorMessages[statusCode] || k8sMessage || "Failed to create job";
        res.status(statusCode).json({ error: msg });

Comment thread backend/src/server.js
Comment on lines +927 to +940
let msg;

if (statusCode === 409) {
const queueName = queueManifest?.metadata?.name || "unknown";
msg = `A queue named '${queueName}' already exists.`;
} else if (statusCode === 403) {
msg = "Permission denied. Check your cluster RBAC permissions.";
} else if (statusCode === 422) {
msg = "Invalid queue specification: " + k8sMessage;
} else {
msg = k8sMessage || "Failed to create queue";
}

res.status(statusCode).json({ error: msg });
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This if-else if chain for handling errors can be refactored into a more concise form using an object to map status codes to messages. This will make the code easier to read and maintain.

        const errorMessages = {
            409: `A queue named '${queueManifest?.metadata?.name || "unknown"}' already exists.`,
            403: "Permission denied. Check your cluster RBAC permissions.",
            422: `Invalid queue specification: ${k8sMessage}`,
        };
        const msg = errorMessages[statusCode] || k8sMessage || "Failed to create queue";
        res.status(statusCode).json({ error: msg });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants