refactor out common dependenceis
This commit is contained in:
1 parent
ddf3e8251d
commit
dc321580c3
20 files changed
+170
-233
No files matched your search
@@ -1,5 +1,4 @@
|
||||
import { createAnnouncementValidation } from "../validation/joi.js";
|
||||
import { asyncHandler } from "../utils/errorUtils.js";
|
||||
|
||||
const SERVICE_NAME = "announcementController";
|
||||
|
||||
@@ -10,10 +9,9 @@ const SERVICE_NAME = "announcementController";
|
||||
* @class AnnouncementController
|
||||
*/
|
||||
|
||||
class AnnouncementController {
|
||||
constructor(db, stringService) {
|
||||
this.db = db;
|
||||
this.stringService = stringService;
|
||||
class AnnouncementController extends BaseController {
|
||||
constructor(commonDependencies) {
|
||||
super(commonDependencies);
|
||||
this.createAnnouncement = this.createAnnouncement.bind(this);
|
||||
this.getAnnouncement = this.getAnnouncement.bind(this);
|
||||
}
|
||||
|
||||
@@ -27,25 +27,19 @@ class AuthController extends BaseController {
|
||||
/**
|
||||
* Creates an instance of AuthController.
|
||||
*
|
||||
* @param {Object} commonDependencies - Common dependencies injected into the controller
|
||||
* @param {Object} dependencies - The dependencies required by the controller
|
||||
* @param {Object} dependencies.db - Database service for data operations
|
||||
* @param {Object} dependencies.settingsService - Service for application settings
|
||||
* @param {Object} dependencies.emailService - Service for email operations
|
||||
* @param {Object} dependencies.jobQueue - Service for job queue operations
|
||||
* @param {Object} dependencies.stringService - Service for string/localization
|
||||
* @param {Object} dependencies.logger - Logger service
|
||||
* @param {Object} dependencies.userService - User business logic service
|
||||
*/
|
||||
constructor({ db, settingsService, emailService, jobQueue, stringService, logger, userService, errorService }) {
|
||||
super();
|
||||
this.db = db;
|
||||
constructor(commonDependencies, { settingsService, emailService, jobQueue, userService }) {
|
||||
super(commonDependencies);
|
||||
this.settingsService = settingsService;
|
||||
this.emailService = emailService;
|
||||
this.jobQueue = jobQueue;
|
||||
this.stringService = stringService;
|
||||
this.logger = logger;
|
||||
this.userService = userService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,83 @@
|
||||
import { asyncHandler } from "../service/infrastructure/errorService.js";
|
||||
import { AppError } from "../service/infrastructure/errorService.js";
|
||||
|
||||
export const createCommonDependencies = (serviceRegistry, dbServiceName, loggerServiceName, errorServiceName, stringServiceName) => {
|
||||
return {
|
||||
db: serviceRegistry.get(dbServiceName),
|
||||
errorService: serviceRegistry.get(errorServiceName),
|
||||
logger: serviceRegistry.get(loggerServiceName),
|
||||
stringService: serviceRegistry.get(stringServiceName),
|
||||
};
|
||||
};
|
||||
|
||||
class BaseController {
|
||||
constructor() {
|
||||
this.asyncHandler = asyncHandler;
|
||||
constructor({ db, logger, errorService, ...additionalDependencies }) {
|
||||
this.db = db;
|
||||
this.logger = logger;
|
||||
this.errorService = errorService;
|
||||
Object.assign(this, additionalDependencies);
|
||||
|
||||
this.asyncHandler = (fn, serviceName, methodName) => {
|
||||
return async (req, res, next) => {
|
||||
try {
|
||||
await fn(req, res, next);
|
||||
} catch (error) {
|
||||
// Handle validation errors
|
||||
if (error.isJoi) {
|
||||
const validationError = this.errorService.createValidationError(error.message, error.details, serviceName, methodName);
|
||||
return next(validationError);
|
||||
}
|
||||
|
||||
if (error.name === "ValidationError") {
|
||||
const validationError = this.errorService.createValidationError("Database validation failed", error.errors, serviceName, methodName);
|
||||
return next(validationError);
|
||||
}
|
||||
|
||||
if (error.name === "CastError") {
|
||||
const notFoundError = this.errorService.createNotFoundError(
|
||||
"Invalid resource identifier",
|
||||
{ field: error.path, value: error.value },
|
||||
serviceName,
|
||||
methodName
|
||||
);
|
||||
return next(notFoundError);
|
||||
}
|
||||
|
||||
if (error.code === "11000") {
|
||||
const conflictError = this.errorService.createConflictError("Resource already exists", {
|
||||
originalError: error.message,
|
||||
code: error.code,
|
||||
});
|
||||
conflictError.service = serviceName;
|
||||
conflictError.method = methodName;
|
||||
return next(conflictError);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
error.service = error.service || serviceName;
|
||||
error.method = error.method || methodName;
|
||||
return next(error);
|
||||
}
|
||||
|
||||
if (error.status) {
|
||||
const appError = this.errorService.createError(error.message, error.status, serviceName, methodName, {
|
||||
originalError: error.message,
|
||||
stack: error.stack,
|
||||
});
|
||||
return next(appError);
|
||||
}
|
||||
|
||||
// For unknown errors, create a server error
|
||||
const appError = this.errorService.createServerError(error.message || "An unexpected error occurred", {
|
||||
originalError: error.message,
|
||||
stack: error.stack,
|
||||
});
|
||||
appError.service = serviceName;
|
||||
appError.method = methodName;
|
||||
appError.stack = error.stack; // Preserve original stack
|
||||
return next(appError);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
export default BaseController;
|
||||
@@ -26,20 +26,15 @@ class CheckController extends BaseController {
|
||||
/**
|
||||
* Creates an instance of CheckController.
|
||||
*
|
||||
* @param {Object} commonDependencies - Common dependencies injected into the controller
|
||||
* @param {Object} dependencies - The dependencies required by the controller
|
||||
* @param {Object} dependencies.db - Database service for data operations
|
||||
* @param {Object} dependencies.settingsService - Service for application settings
|
||||
* @param {Object} dependencies.stringService - Service for string/localization
|
||||
* @param {Object} dependencies.checkService - Check business logic service
|
||||
* @param {Object} dependencies.errorService - Error service for error handling
|
||||
*/
|
||||
constructor({ db, settingsService, stringService, checkService, errorService }) {
|
||||
super();
|
||||
this.db = db;
|
||||
constructor(commonDependencies, { settingsService, checkService }) {
|
||||
super(commonDependencies);
|
||||
this.settingsService = settingsService;
|
||||
this.stringService = stringService;
|
||||
this.checkService = checkService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,15 +12,13 @@ import BaseController from "./baseController.js";
|
||||
class DiagnosticController extends BaseController {
|
||||
/**
|
||||
* Creates an instance of DiagnosticController.
|
||||
*
|
||||
* @param {Object} commonDependencies - Common dependencies injected into the controller
|
||||
* @param {Object} dependencies - The dependencies required by the controller
|
||||
* @param {Object} dependencies.diagnosticService - Service for system diagnostics and monitoring
|
||||
* @param {Object} dependencies.errorService - Service for error handling
|
||||
*/
|
||||
constructor({ diagnosticService, errorService }) {
|
||||
super();
|
||||
constructor(commonDependencies, { diagnosticService }) {
|
||||
super(commonDependencies);
|
||||
this.diagnosticService = diagnosticService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -9,16 +9,12 @@ const SERVICE_NAME = "inviteController";
|
||||
class InviteController extends BaseController {
|
||||
/**
|
||||
* Creates a new InviteController instance
|
||||
* @param {Object} dependencies - Dependencies injected into the controller
|
||||
* @param {Object} dependencies.stringService - Service for internationalized strings
|
||||
* @param {Object} dependencies.inviteServ ice - Service for invite-related operations
|
||||
* @param {Object} dependencies.errorService - Service for error handling
|
||||
* @param {Object} commonDependencies - Common dependencies injected into the controller
|
||||
* @param {Object} dependencies.inviteService - Service for invite-related operations
|
||||
*/
|
||||
constructor({ stringService, inviteService, errorService }) {
|
||||
super();
|
||||
this.stringService = stringService;
|
||||
constructor(commonDependencies, { inviteService }) {
|
||||
super(commonDependencies);
|
||||
this.inviteService = inviteService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,10 +2,8 @@ import BaseController from "./baseController.js";
|
||||
const SERVICE_NAME = "LogController";
|
||||
|
||||
class LogController extends BaseController {
|
||||
constructor({ logger, errorService }) {
|
||||
super();
|
||||
this.logger = logger;
|
||||
this.errorService = errorService;
|
||||
constructor(commonDependencies) {
|
||||
super(commonDependencies);
|
||||
}
|
||||
|
||||
getLogs = this.asyncHandler(
|
||||
|
||||
@@ -12,14 +12,10 @@ import BaseController from "./baseController.js";
|
||||
const SERVICE_NAME = "maintenanceWindowController";
|
||||
|
||||
class MaintenanceWindowController extends BaseController {
|
||||
constructor({ db, settingsService, stringService, maintenanceWindowService, errorService }) {
|
||||
super();
|
||||
this.db = db;
|
||||
constructor(commonDependencies, { settingsService, maintenanceWindowService }) {
|
||||
super(commonDependencies);
|
||||
this.settingsService = settingsService;
|
||||
this.stringService = stringService;
|
||||
this.maintenanceWindowService = maintenanceWindowService;
|
||||
this.errorService = errorService;
|
||||
this.asyncHandler = errorService.asyncHandler;
|
||||
}
|
||||
|
||||
createMaintenanceWindows = this.asyncHandler(
|
||||
|
||||
@@ -18,16 +18,12 @@ import BaseController from "./baseController.js";
|
||||
|
||||
const SERVICE_NAME = "monitorController";
|
||||
class MonitorController extends BaseController {
|
||||
constructor({ db, settingsService, jobQueue, stringService, emailService, monitorService, errorService }) {
|
||||
super();
|
||||
this.db = db;
|
||||
constructor(commonDependencies, { settingsService, jobQueue, emailService, monitorService }) {
|
||||
super(commonDependencies);
|
||||
this.settingsService = settingsService;
|
||||
this.jobQueue = jobQueue;
|
||||
this.stringService = stringService;
|
||||
this.emailService = emailService;
|
||||
this.monitorService = monitorService;
|
||||
this.errorService = errorService;
|
||||
this.asyncHandler = errorService.asyncHandler;
|
||||
}
|
||||
|
||||
async verifyTeamAccess(teamId, monitorId) {
|
||||
|
||||
@@ -4,14 +4,10 @@ import BaseController from "./baseController.js";
|
||||
const SERVICE_NAME = "NotificationController";
|
||||
|
||||
class NotificationController extends BaseController {
|
||||
constructor({ notificationService, stringService, statusService, db, errorService }) {
|
||||
super();
|
||||
constructor(commonDependencies, { notificationService, statusService }) {
|
||||
super(commonDependencies);
|
||||
this.notificationService = notificationService;
|
||||
this.stringService = stringService;
|
||||
this.statusService = statusService;
|
||||
this.db = db;
|
||||
this.errorService = errorService;
|
||||
this.asyncHandler = errorService.asyncHandler;
|
||||
}
|
||||
|
||||
testNotification = this.asyncHandler(
|
||||
|
||||
@@ -2,11 +2,9 @@ import BaseController from "./baseController.js";
|
||||
const SERVICE_NAME = "JobQueueController";
|
||||
|
||||
class JobQueueController extends BaseController {
|
||||
constructor({ jobQueue, stringService, errorService }) {
|
||||
super();
|
||||
constructor(commonDependencies, { jobQueue }) {
|
||||
super(commonDependencies);
|
||||
this.jobQueue = jobQueue;
|
||||
this.stringService = stringService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
getMetrics = this.asyncHandler(
|
||||
|
||||
@@ -5,13 +5,10 @@ import BaseController from "./baseController.js";
|
||||
const SERVICE_NAME = "SettingsController";
|
||||
|
||||
class SettingsController extends BaseController {
|
||||
constructor({ db, settingsService, stringService, emailService, errorService }) {
|
||||
super();
|
||||
this.db = db;
|
||||
constructor(commonDependencies, { settingsService, emailService }) {
|
||||
super(commonDependencies);
|
||||
this.settingsService = settingsService;
|
||||
this.stringService = stringService;
|
||||
this.emailService = emailService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
buildAppSettings = (dbSettings) => {
|
||||
|
||||
@@ -4,11 +4,8 @@ import BaseController from "./baseController.js";
|
||||
const SERVICE_NAME = "statusPageController";
|
||||
|
||||
class StatusPageController extends BaseController {
|
||||
constructor({ db, stringService, errorService }) {
|
||||
super();
|
||||
this.db = db;
|
||||
this.stringService = stringService;
|
||||
this.errorService = errorService;
|
||||
constructor(commonDependencies) {
|
||||
super(commonDependencies);
|
||||
}
|
||||
|
||||
createStatusPage = this.asyncHandler(
|
||||
|
||||
+33
-47
@@ -7,11 +7,13 @@ import express from "express";
|
||||
import helmet from "helmet";
|
||||
import cors from "cors";
|
||||
import compression from "compression";
|
||||
import { Logger } from "./utils/logger.js";
|
||||
import logger from "./utils/logger.js";
|
||||
import { verifyJWT } from "./middleware/verifyJWT.js";
|
||||
import { handleErrors } from "./middleware/handleErrors.js";
|
||||
import { responseHandler } from "./middleware/responseHandler.js";
|
||||
import { fileURLToPath } from "url";
|
||||
import { createCommonDependencies } from "./controllers/baseController.js";
|
||||
|
||||
import AuthRoutes from "./routes/authRoute.js";
|
||||
import AuthController from "./controllers/authController.js";
|
||||
@@ -248,6 +250,7 @@ const startApp = async () => {
|
||||
db,
|
||||
settingsService,
|
||||
stringService,
|
||||
errorService,
|
||||
});
|
||||
const diagnosticService = new DiagnosticService();
|
||||
const inviteService = new InviteService({
|
||||
@@ -261,6 +264,7 @@ const startApp = async () => {
|
||||
db,
|
||||
settingsService,
|
||||
stringService,
|
||||
errorService,
|
||||
});
|
||||
const monitorService = new MonitorService({
|
||||
db,
|
||||
@@ -275,6 +279,7 @@ const startApp = async () => {
|
||||
// Register services
|
||||
// ServiceRegistry.register(JobQueue.SERVICE_NAME, jobQueue);
|
||||
// ServiceRegistry.register(JobQueue.SERVICE_NAME, pulseQueue);
|
||||
ServiceRegistry.register(Logger.SERVICE_NAME, logger);
|
||||
ServiceRegistry.register(JobQueue.SERVICE_NAME, superSimpleQueue);
|
||||
ServiceRegistry.register(ErrorService.SERVICE_NAME, errorService);
|
||||
ServiceRegistry.register(MongoDB.SERVICE_NAME, db);
|
||||
@@ -305,82 +310,63 @@ const startApp = async () => {
|
||||
process.on("SIGTERM", shutdown);
|
||||
|
||||
//Create controllers
|
||||
const authController = new AuthController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
|
||||
const commonDependencies = createCommonDependencies(
|
||||
ServiceRegistry,
|
||||
MongoDB.SERVICE_NAME,
|
||||
Logger.SERVICE_NAME,
|
||||
ErrorService.SERVICE_NAME,
|
||||
StringService.SERVICE_NAME
|
||||
);
|
||||
|
||||
const authController = new AuthController(commonDependencies, {
|
||||
settingsService: ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
emailService: ServiceRegistry.get(EmailService.SERVICE_NAME),
|
||||
jobQueue: ServiceRegistry.get(JobQueue.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
logger: logger,
|
||||
userService: ServiceRegistry.get(UserService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const monitorController = new MonitorController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
const monitorController = new MonitorController(commonDependencies, {
|
||||
settingsService: ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
jobQueue: ServiceRegistry.get(JobQueue.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
emailService: ServiceRegistry.get(EmailService.SERVICE_NAME),
|
||||
monitorService: ServiceRegistry.get(MonitorService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const settingsController = new SettingsController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
const settingsController = new SettingsController(commonDependencies, {
|
||||
settingsService: ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
emailService: ServiceRegistry.get(EmailService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const checkController = new CheckController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
const checkController = new CheckController(commonDependencies, {
|
||||
settingsService: ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
checkService: ServiceRegistry.get(CheckService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const inviteController = new InviteController({
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
const inviteController = new InviteController(commonDependencies, {
|
||||
inviteService: ServiceRegistry.get(InviteService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const maintenanceWindowController = new MaintenanceWindowController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
const maintenanceWindowController = new MaintenanceWindowController(commonDependencies, {
|
||||
settingsService: ServiceRegistry.get(SettingsService.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
maintenanceWindowService: ServiceRegistry.get(MaintenanceWindowService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const queueController = new QueueController({
|
||||
const queueController = new QueueController(commonDependencies, {
|
||||
jobQueue: ServiceRegistry.get(JobQueue.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const logController = new LogController({ logger, errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME) });
|
||||
const logController = new LogController(commonDependencies);
|
||||
|
||||
const statusPageController = new StatusPageController({
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
const statusPageController = new StatusPageController(commonDependencies);
|
||||
|
||||
const notificationController = new NotificationController({
|
||||
const notificationController = new NotificationController(commonDependencies, {
|
||||
notificationService: ServiceRegistry.get(NotificationService.SERVICE_NAME),
|
||||
stringService: ServiceRegistry.get(StringService.SERVICE_NAME),
|
||||
statusService: ServiceRegistry.get(StatusService.SERVICE_NAME),
|
||||
db: ServiceRegistry.get(MongoDB.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
const diagnosticController = new DiagnosticController({
|
||||
const diagnosticController = new DiagnosticController(commonDependencies, {
|
||||
diagnosticService: ServiceRegistry.get(DiagnosticService.SERVICE_NAME),
|
||||
errorService: ServiceRegistry.get(ErrorService.SERVICE_NAME),
|
||||
});
|
||||
|
||||
//Create routes
|
||||
@@ -393,9 +379,9 @@ const startApp = async () => {
|
||||
const queueRoutes = new QueueRoutes(queueController);
|
||||
const logRoutes = new LogRoutes(logController);
|
||||
const statusPageRoutes = new StatusPageRoutes(statusPageController);
|
||||
|
||||
const notificationRoutes = new NotificationRoutes(notificationController);
|
||||
const diagnosticRoutes = new DiagnosticRoutes(diagnosticController);
|
||||
|
||||
// Middleware
|
||||
app.use(express.static(frontendPath));
|
||||
app.use(responseHandler);
|
||||
@@ -438,16 +424,16 @@ const startApp = async () => {
|
||||
|
||||
//routes
|
||||
app.use("/api/v1/auth", authRoutes.getRouter());
|
||||
app.use("/api/v1/checks", verifyJWT, checkRoutes.getRouter());
|
||||
app.use("/api/v1/diagnostic", verifyJWT, diagnosticRoutes.getRouter());
|
||||
app.use("/api/v1/invite", inviteRoutes.getRouter());
|
||||
app.use("/api/v1/logs", verifyJWT, logRoutes.getRouter());
|
||||
app.use("/api/v1/maintenance-window", verifyJWT, maintenanceWindowRoutes.getRouter());
|
||||
app.use("/api/v1/monitors", verifyJWT, monitorRoutes.getRouter());
|
||||
app.use("/api/v1/notifications", verifyJWT, notificationRoutes.getRouter());
|
||||
app.use("/api/v1/queue", verifyJWT, queueRoutes.getRouter());
|
||||
app.use("/api/v1/settings", verifyJWT, settingsRoutes.getRouter());
|
||||
app.use("/api/v1/checks", verifyJWT, checkRoutes.getRouter());
|
||||
app.use("/api/v1/invite", inviteRoutes.getRouter());
|
||||
app.use("/api/v1/maintenance-window", verifyJWT, maintenanceWindowRoutes.getRouter());
|
||||
app.use("/api/v1/queue", verifyJWT, queueRoutes.getRouter());
|
||||
app.use("/api/v1/logs", verifyJWT, logRoutes.getRouter());
|
||||
app.use("/api/v1/status-page", statusPageRoutes.getRouter());
|
||||
app.use("/api/v1/notifications", verifyJWT, notificationRoutes.getRouter());
|
||||
app.use("/api/v1/diagnostic", verifyJWT, diagnosticRoutes.getRouter());
|
||||
|
||||
app.use("/api/v1/health", (req, res) => {
|
||||
res.json({
|
||||
|
||||
@@ -3,37 +3,30 @@ const SERVICE_NAME = "checkService";
|
||||
class CheckService {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
|
||||
constructor({ db, settingsService, stringService }) {
|
||||
constructor({ db, settingsService, stringService, errorService }) {
|
||||
this.db = db;
|
||||
this.settingsService = settingsService;
|
||||
this.stringService = stringService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
getChecksByMonitor = async ({ monitorId, query, teamId }) => {
|
||||
if (!monitorId) {
|
||||
throw new Error("No monitor ID in request");
|
||||
throw this.errorService.createBadRequestError("No monitor ID in request");
|
||||
}
|
||||
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
const monitor = await this.db.getMonitorById(monitorId);
|
||||
|
||||
if (!monitor) {
|
||||
const err = new Error("Monitor not found");
|
||||
err.status = 404;
|
||||
err.service = SERVICE_NAME;
|
||||
err.method = "getChecksByMonitor";
|
||||
throw err;
|
||||
throw this.errorService.createNotFoundError("Monitor not found");
|
||||
}
|
||||
|
||||
if (!monitor.teamId.equals(teamId)) {
|
||||
const err = new Error("Unauthorized");
|
||||
err.status = 403;
|
||||
err.service = SERVICE_NAME;
|
||||
err.method = "getChecksByMonitor";
|
||||
throw err;
|
||||
throw this.errorService.createAuthorizationError();
|
||||
}
|
||||
|
||||
let { type, sortOrder, dateRange, filter, ack, page, rowsPerPage, status } = query;
|
||||
@@ -55,7 +48,7 @@ class CheckService {
|
||||
let { sortOrder, dateRange, filter, ack, page, rowsPerPage } = query;
|
||||
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
const checkData = await this.db.getChecksByTeam({
|
||||
@@ -72,7 +65,7 @@ class CheckService {
|
||||
|
||||
getChecksSummaryByTeamId = async ({ teamId }) => {
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
const summary = await this.db.getChecksSummaryByTeamId({ teamId });
|
||||
@@ -81,11 +74,11 @@ class CheckService {
|
||||
|
||||
ackCheck = async ({ checkId, teamId, ack }) => {
|
||||
if (!checkId) {
|
||||
throw new Error("No check ID in request");
|
||||
throw this.errorService.createBadRequestError("No check ID in request");
|
||||
}
|
||||
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
const updatedCheck = await this.db.ackCheck(checkId, teamId, ack);
|
||||
@@ -95,20 +88,16 @@ class CheckService {
|
||||
ackAllChecks = async ({ monitorId, path, teamId, ack }) => {
|
||||
if (path === "monitor") {
|
||||
if (!monitorId) {
|
||||
throw new Error("No monitor ID in request");
|
||||
throw this.errorService.createBadRequestError("No monitor ID in request");
|
||||
}
|
||||
|
||||
const monitor = await this.db.getMonitorById(monitorId);
|
||||
if (!monitor) {
|
||||
throw new Error("Monitor not found");
|
||||
throw this.errorService.createNotFoundError("Monitor not found");
|
||||
}
|
||||
|
||||
if (!monitor.teamId.equals(teamId)) {
|
||||
const err = new Error("Unauthorized");
|
||||
err.status = 403;
|
||||
err.service = SERVICE_NAME;
|
||||
err.method = "ackAllChecks";
|
||||
throw err;
|
||||
throw this.errorService.createAuthorizationError();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,29 +107,21 @@ class CheckService {
|
||||
|
||||
deleteChecks = async ({ monitorId, teamId }) => {
|
||||
if (!monitorId) {
|
||||
throw new Error("No monitor ID in request");
|
||||
throw this.errorService.createBadRequestError("No monitor ID in request");
|
||||
}
|
||||
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
const monitor = await this.db.getMonitorById(monitorId);
|
||||
|
||||
if (!monitor) {
|
||||
const err = new Error("Monitor not found");
|
||||
err.status = 404;
|
||||
err.service = SERVICE_NAME;
|
||||
err.method = "deleteChecks";
|
||||
throw err;
|
||||
throw this.errorService.createNotFoundError("Monitor not found");
|
||||
}
|
||||
|
||||
if (!monitor.teamId.equals(teamId)) {
|
||||
const err = new Error("Unauthorized");
|
||||
err.status = 403;
|
||||
err.service = SERVICE_NAME;
|
||||
err.method = "deleteChecks";
|
||||
throw err;
|
||||
throw this.errorService.createAuthorizationError();
|
||||
}
|
||||
|
||||
const deletedCount = await this.db.deleteChecks(monitorId);
|
||||
@@ -148,7 +129,7 @@ class CheckService {
|
||||
};
|
||||
deleteChecksByTeamId = async ({ teamId }) => {
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
const deletedCount = await this.db.deleteChecksByTeamId(teamId);
|
||||
|
||||
@@ -2,10 +2,11 @@ const SERVICE_NAME = "maintenanceWindowService";
|
||||
|
||||
class MaintenanceWindowService {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
constructor({ db, settingsService, stringService }) {
|
||||
constructor({ db, settingsService, stringService, errorService }) {
|
||||
this.db = db;
|
||||
this.settingsService = settingsService;
|
||||
this.stringService = stringService;
|
||||
this.errorService = errorService;
|
||||
}
|
||||
|
||||
createMaintenanceWindow = async ({ teamId, body }) => {
|
||||
@@ -15,11 +16,7 @@ class MaintenanceWindowService {
|
||||
const unauthorizedMonitors = monitors.filter((monitor) => !monitor.teamId.equals(teamId));
|
||||
|
||||
if (unauthorizedMonitors.length > 0) {
|
||||
const error = new Error("Unauthorized access to one or more monitors");
|
||||
error.status = 403;
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "createMaintenanceWindows";
|
||||
throw error;
|
||||
throw this.errorService.createAuthorizationError();
|
||||
}
|
||||
|
||||
const dbTransactions = monitorIds.map((monitorId) => {
|
||||
|
||||
@@ -13,7 +13,6 @@ class MonitorService {
|
||||
this.papaparse = papaparse;
|
||||
this.logger = logger;
|
||||
this.errorService = errorService;
|
||||
this.asyncHandler = errorService.asyncHandler;
|
||||
}
|
||||
|
||||
verifyTeamAccess = async ({ teamId, monitorId }) => {
|
||||
|
||||
@@ -154,23 +154,23 @@ class UserService {
|
||||
deleteUser = async (user) => {
|
||||
const email = user?.email;
|
||||
if (!email) {
|
||||
throw new Error("No email in request");
|
||||
throw this.errorService.createBadRequestError("No email in request");
|
||||
}
|
||||
|
||||
const teamId = user?.teamId;
|
||||
const userId = user?._id;
|
||||
|
||||
if (!teamId) {
|
||||
throw new Error("No team ID in request");
|
||||
throw this.errorService.createBadRequestError("No team ID in request");
|
||||
}
|
||||
|
||||
if (!userId) {
|
||||
throw new Error("No user ID in request");
|
||||
throw this.errorService.createBadRequestError("No user ID in request");
|
||||
}
|
||||
|
||||
const roles = user?.role;
|
||||
if (roles.includes("demo")) {
|
||||
throw new Error("Demo user cannot be deleted");
|
||||
throw this.errorService.createBadRequestError("Demo user cannot be deleted");
|
||||
}
|
||||
|
||||
// 1. Find all the monitors associated with the team ID if superadmin
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
class AppError extends Error {
|
||||
export class AppError extends Error {
|
||||
constructor(message, status = 500, service = null, method = null, details = null) {
|
||||
super(message);
|
||||
this.status = status;
|
||||
@@ -96,66 +96,3 @@ class ErrorService {
|
||||
}
|
||||
|
||||
export default ErrorService;
|
||||
|
||||
export const asyncHandler = (fn, serviceName, methodName) => {
|
||||
return async (req, res, next) => {
|
||||
try {
|
||||
await fn(req, res, next);
|
||||
} catch (error) {
|
||||
// Handle validation errors
|
||||
if (error.isJoi) {
|
||||
const validationError = this.createValidationError(error.message, error.details, serviceName, methodName);
|
||||
return next(validationError);
|
||||
}
|
||||
|
||||
if (error.name === "ValidationError") {
|
||||
const validationError = this.createValidationError("Database validation failed", error.errors, serviceName, methodName);
|
||||
return next(validationError);
|
||||
}
|
||||
|
||||
if (error.name === "CastError") {
|
||||
const notFoundError = this.createNotFoundError(
|
||||
"Invalid resource identifier",
|
||||
{ field: error.path, value: error.value },
|
||||
serviceName,
|
||||
methodName
|
||||
);
|
||||
return next(notFoundError);
|
||||
}
|
||||
|
||||
if (error.code === "11000") {
|
||||
const conflictError = this.createConflictError("Resource already exists", {
|
||||
originalError: error.message,
|
||||
code: error.code,
|
||||
});
|
||||
conflictError.service = serviceName;
|
||||
conflictError.method = methodName;
|
||||
return next(conflictError);
|
||||
}
|
||||
|
||||
if (error instanceof AppError) {
|
||||
error.service = error.service || serviceName;
|
||||
error.method = error.method || methodName;
|
||||
return next(error);
|
||||
}
|
||||
|
||||
if (error.status) {
|
||||
const appError = this.createError(error.message, error.status, serviceName, methodName, {
|
||||
originalError: error.message,
|
||||
stack: error.stack,
|
||||
});
|
||||
return next(appError);
|
||||
}
|
||||
|
||||
// For unknown errors, create a server error
|
||||
const appError = this.createServerError(error.message || "An unexpected error occurred", {
|
||||
originalError: error.message,
|
||||
stack: error.stack,
|
||||
});
|
||||
appError.service = serviceName;
|
||||
appError.method = methodName;
|
||||
appError.stack = error.stack; // Preserve original stack
|
||||
return next(appError);
|
||||
}
|
||||
};
|
||||
};
|
||||
@@ -2,7 +2,10 @@ import { createLogger, format, transports } from "winston";
|
||||
import dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
|
||||
const SERVICE_NAME = "Logger";
|
||||
|
||||
class Logger {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
constructor() {
|
||||
this.logCache = [];
|
||||
this.maxCacheSize = 1000;
|
||||
|
||||
Reference in new issue
Block a user