Skip to content
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

feat: be/consistent response middleare #1591

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from

Conversation

ajhollid
Copy link
Collaborator

This PR adds a resonse handling middleware to enforce consistent network responses from the Server. This will help with future collaboration as there is a clearly defined method of creating and returning responses.

Consistency will be key in creating a predictable API, which will lead to better handling of resonses on the front end.

  • Implement a response handling middleware for consistent responses from the server
  • Use response middleware in all controller functions
  • Refactor out several hardcoded strings
  • Add correct error code to login errors (no error code => 401)

Copy link

@llamapreview llamapreview bot left a comment

Choose a reason for hiding this comment

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

Auto Pull Request Review from LlamaPReview

Large PR Notification

Dear contributor,

Thank you for your substantial contribution to this project. LlamaPReview has detected that this Pull Request contains a large volume of changes, which exceeds our current processing capacity.

Details:

  • PR and related contents total size: Approximately 52,165 characters
  • Current limit: 50,000 characters

Next steps:

  1. Consider breaking this PR into smaller, more focused changes if possible.
  2. For manual review, please reach out to your team members or maintainers.

We appreciate your understanding and commitment to improving this project. Your contributions are valuable, and we want to ensure they receive the attention they deserve.

LlamaPReview is continuously evolving to better serve the community. Share your thoughts on handling large PRs in our GitHub Discussions - your feedback helps us improve and expand our capabilities.

If you have any questions or need assistance, our community and support team are here to help.

Best regards,
LlamaPReview Team

Copy link

coderabbitai bot commented Jan 20, 2025

Walkthrough

The pull request introduces a comprehensive refactoring of response handling across multiple server-side controllers and middleware. A new responseHandler middleware has been added to standardize response formats, replacing traditional Express response methods with custom res.success() and res.error() methods. This change affects multiple controllers, including authentication, monitoring, invites, and maintenance windows. Additionally, a new set of success messages has been introduced to provide more consistent and descriptive feedback across different application operations.

Changes

File Change Summary
Server/index.js Added responseHandler middleware
Server/middleware/responseHandler.js New middleware with success and error response methods
Server/middleware/handleErrors.js Updated error response handling
Server/utils/messages.js Added numerous success messages for various controllers
Server/controllers/* Replaced .status(200).json() with .success() across multiple controllers

Sequence Diagram

sequenceDiagram
    Client->>Express Server: HTTP Request
    Express Server->>ResponseHandler: Apply middleware
    ResponseHandler-->>Response: Add custom methods
    Response->>Controller: Process request
    Controller-->>Response: Generate response
    Response->>Client: Send standardized response
Loading

The sequence diagram illustrates how the new responseHandler middleware intercepts requests, adds custom response methods, and allows controllers to generate standardized responses before sending them back to the client.

Finishing Touches

  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🔭 Outside diff range comments (1)
Server/controllers/maintenanceWindowController.js (1)

Line range hint 31-47: Lose yourself in the transactions - we need better error handling! 🎤

The Promise.all() call for DB transactions needs proper error handling and rollback capability.

Consider implementing a transaction wrapper:

-const dbTransactions = monitorIds.map((monitorId) => {
+const session = await this.db.startSession();
+try {
+  await session.startTransaction();
+  const dbTransactions = monitorIds.map((monitorId) => {
     return this.db.createMaintenanceWindow({
       teamId,
       monitorId,
       name: req.body.name,
       active: req.body.active ? req.body.active : true,
       repeat: req.body.repeat,
       start: req.body.start,
       end: req.body.end,
+      session,
     });
-});
-await Promise.all(dbTransactions);
+  });
+  await Promise.all(dbTransactions);
+  await session.commitTransaction();
+} catch (error) {
+  await session.abortTransaction();
+  throw error;
+} finally {
+  session.endSession();
+}
🧹 Nitpick comments (7)
Server/controllers/statusPageController.js (1)

Line range hint 1-52: Yo, these changes are straight fire! 🔥

The refactoring to use the new response middleware is a solid architectural improvement. It:

  • Makes the response format consistent across all endpoints
  • Centralizes success message handling
  • Removes duplicate response structure code
  • Makes the API more predictable for frontend consumers

Keep this style consistent across other controllers too!

Server/controllers/queueController.js (1)

14-14: Knees weak, code's heavy - let's make these returns steady! 🎯

The use of return statements with res.success() is inconsistent across methods. getMetrics doesn't use return while the other methods do. Since we're not using the return value, we should be consistent and remove unnecessary return statements.

Make it consistent across all methods:

-      return res.success({
+      res.success({

Also applies to: 27-27, 40-40, 52-52

Server/middleware/responseHandler.js (2)

1-8: Yo dawg, let's make this response handler consistent!

The success method implementation has inconsistent object property shorthand usage. Line 5 uses the long form msg: msg while other properties could benefit from the same consistency.

-			msg: msg,
-			data: data,
+			msg,
+			data,

1-18: Knees weak, arms heavy: Let's type-check this middleware!

Consider adding TypeScript or JSDoc type definitions for better integration with Express types. This would help catch potential issues at compile time and improve IDE support.

/**
 * @typedef {Object} ResponseOptions
 * @property {number} [status=200] - HTTP status code
 * @property {string} [msg="OK"] - Response message
 * @property {any} [data=null] - Response payload
 */

/**
 * @param {import('express').Request} req
 * @param {import('express').Response} res
 * @param {import('express').NextFunction} next
 */
Server/controllers/inviteController.js (2)

Line range hint 22-35: Lose yourself in the documentation!

The JSDoc is missing the return type for the success response structure.

 * @returns {Object} The response object with a success status, a message indicating the sending of the invitation, and the invitation token.
+* @returns {Object} Returns res.success() with { msg: string, data: { token: string } }

87-91: Mom's spaghetti code: Handle email errors properly!

Consider using the error response handler for email sending failures instead of just logging them.

-				.catch((error) => {
-					logger.error({
-						message: error.message,
-						service: SERVICE_NAME,
-						method: "issueInvitation",
-						stack: error.stack,
-					});
-				});
+				.catch((error) => {
+					next(handleError(error, SERVICE_NAME, "issueInvitation"));
+					return;
+				});
Server/utils/messages.js (1)

Line range hint 76-91: These success messages be spittin' straight fire! 🔥

The new success messages maintain consistent formatting and provide clear feedback. However, some messages could be more specific about the action performed.

Consider enhancing these messages with more context:

-  AUTH_CREATE_USER: "User created successfully",
+  AUTH_CREATE_USER: "User account created and ready for login",
-  AUTH_LOGIN_USER: "User logged in successfully",
+  AUTH_LOGIN_USER: "User authenticated and session created successfully",
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5f94041 and 9f43336.

📒 Files selected for processing (13)
  • Server/controllers/authController.js (11 hunks)
  • Server/controllers/checkController.js (6 hunks)
  • Server/controllers/controllerUtils.js (1 hunks)
  • Server/controllers/inviteController.js (3 hunks)
  • Server/controllers/maintenanceWindowController.js (6 hunks)
  • Server/controllers/monitorController.js (15 hunks)
  • Server/controllers/queueController.js (4 hunks)
  • Server/controllers/settingsController.js (2 hunks)
  • Server/controllers/statusPageController.js (2 hunks)
  • Server/index.js (2 hunks)
  • Server/middleware/handleErrors.js (1 hunks)
  • Server/middleware/responseHandler.js (1 hunks)
  • Server/utils/messages.js (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (7)
Server/middleware/handleErrors.js (1)

14-17: Straight fire error handling! 🔥

Clean implementation using the new response handler while maintaining comprehensive error logging.

Server/controllers/controllerUtils.js (1)

16-23: Vomit on his sweater already: Let's verify error handling!

The removal of try-catch simplifies the code, but we should verify that all callers properly handle the potential errors:

  • URL parsing errors
  • SSL checker failures
  • Certificate validation errors
✅ Verification successful

Yo dawg, error handling is tight like mom's spaghetti!

The error handling is solid and well-tested:

  • All errors are caught in monitorController's try-catch block
  • Proper error middleware handles different failure scenarios
  • Comprehensive test coverage for all error cases
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find all usages of fetchMonitorCertificate to verify error handling
rg -l "fetchMonitorCertificate" | xargs rg -A 10 "fetchMonitorCertificate"

Length of output: 11854

Server/controllers/inviteController.js (1)

68-71: Success response looking clean! 👌

Good use of standardized success messages from utils.

Server/index.js (1)

276-277: Yo dawg, that middleware placement is on point! 🎯

The responseHandler middleware is strategically positioned after Swagger UI setup but before route definitions, ensuring consistent response handling across all API endpoints.

Server/controllers/checkController.js (1)

37-41: Mom's spaghetti moment: This response is clean and ready! 🍝

The new response format using res.success() is clean and consistent.

Server/controllers/authController.js (1)

156-158: Straight fire error handling! 🔥

Consistent setting of 401 status for authentication failures improves API reliability.

Also applies to: 187-187

Server/controllers/settingsController.js (1)

15-15: Clean as mom's spaghetti! 👌

Excellent security practice removing the sensitive jwtSecret before sending the response.

🧰 Tools
🪛 Biome (1.9.4)

[error] 15-15: Avoid the delete operator which can impact performance.

Unsafe fix: Use an undefined assignment instead.

(lint/performance/noDelete)

Comment on lines +44 to 47
return res.successs({
msg: successMessages.STATUS_PAGE_BY_URL,
data: statusPage,
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Same typo alert in the second method!

The same spelling mistake appears here too. Gotta keep it consistent with the middleware implementation.

-			return res.successs({
+			return res.success({
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return res.successs({
msg: successMessages.STATUS_PAGE_BY_URL,
data: statusPage,
});
return res.success({
msg: successMessages.STATUS_PAGE_BY_URL,
data: statusPage,
});

Comment on lines +25 to 28
return res.successs({
msg: successMessages.STATUS_PAGE_CREATE,
data: statusPage,
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Yo dawg, fix that typo in res.successs!

There's a typo in the method name - it's spelled with an extra 's'. This needs to be fixed to prevent runtime errors.

-			return res.successs({
+			return res.success({
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return res.successs({
msg: successMessages.STATUS_PAGE_CREATE,
data: statusPage,
});
return res.success({
msg: successMessages.STATUS_PAGE_CREATE,
data: statusPage,
});

@@ -11,8 +11,7 @@ class JobQueueController {
getMetrics = async (req, res, next) => {
try {
const metrics = await this.jobQueue.getMetrics();
res.status(200).json({
success: true,
res.successs({
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Yo dawg, there's a typo that's making me lose my spaghetti! 🍝

There's a typo in the response method - it's spelled with three 's' characters (successs). This will cause runtime errors as the method doesn't exist. The correct spelling should be success.

Fix this in all occurrences:

-      res.successs({
+      res.success({

Also applies to: 27-27, 40-40, 52-52

Comment on lines +27 to 29
return res.successs({
msg: successMessages.QUEUE_GET_METRICS,
data: jobs,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mom's spaghetti moment - we've got a message mix-up! 🤔

The getJobs method is using QUEUE_GET_METRICS as its success message, but this appears to be incorrect. It should probably be using a more appropriate message like QUEUE_GET_JOBS.

Fix the message constant:

       return res.success({
-        msg: successMessages.QUEUE_GET_METRICS,
+        msg: successMessages.QUEUE_GET_JOBS,
         data: jobs,

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +10 to +16
res.error = ({ status = 500, msg = "Internal server erro", data = null }) => {
return res.status(status).json({
success: false,
msg,
data,
});
};
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mom's spaghetti alert: Fix that typo in the error message!

There's a typo in the default error message: "Internal server erro" should be "Internal server error". This could confuse users when they see error responses.

-	res.error = ({ status = 500, msg = "Internal server erro", data = null }) => {
+	res.error = ({ status = 500, msg = "Internal server error", data = null }) => {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
res.error = ({ status = 500, msg = "Internal server erro", data = null }) => {
return res.status(status).json({
success: false,
msg,
data,
});
};
res.error = ({ status = 500, msg = "Internal server error", data = null }) => {
return res.status(status).json({
success: false,
msg,
data,
});
};

Comment on lines +99 to 103

return res.success({
msg: successMessages.CHECK_DELETE,
data: { deletedCount },
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Yo, we need to handle edge cases here! 🎯

The deleteChecks method should verify the deletedCount before sending a success response.

 const deletedCount = await this.db.deleteChecks(req.params.monitorId);
+if (deletedCount === 0) {
+  return res.error({
+    msg: errorMessages.DB_DELETE_CHECKS(req.params.monitorId),
+  });
+}
 return res.success({

Committable suggestion skipped: line range outside the PR's diff.

@@ -449,8 +437,7 @@ class MonitorController {
monitor.isActive = !monitor.isActive;
monitor.status = undefined;
monitor.save();
return res.status(200).json({
success: true,
return res.ssuccess({
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Mom's spaghetti alert! There's a typo in your response method!

Fix the typo in the response method name from ssuccess to success.

-      return res.ssuccess({
+      return res.success({
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return res.ssuccess({
return res.success({

Comment on lines +107 to 110
return res.success({
success: true,
msg: successMessages.MONITOR_STATS_BY_ID,
data: monitorStats,
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Yo dawg, we heard you like success, but you don't need to double up!

Remove the redundant success: true field since res.success() already handles the success status.

 return res.success({
-  success: true,
   msg: successMessages.MONITOR_STATS_BY_ID,
   data: monitorStats,
 });
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return res.success({
success: true,
msg: successMessages.MONITOR_STATS_BY_ID,
data: monitorStats,
return res.success({
msg: successMessages.MONITOR_STATS_BY_ID,
data: monitorStats,

@@ -13,8 +13,7 @@ class SettingsController {
try {
const settings = { ...(await this.settingsService.getSettings()) };
delete settings.jwtSecret;
return res.status(200).json({
success: true,
return res.successs({
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Knees weak, arms heavy, there's a typo in your API!

Fix the typo in the response method name from successs to success.

-      return res.successs({
+      return res.success({
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return res.successs({
return res.success({

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant