Recently, I've been exploring the idea of refactoring this code into a higher order function using TypeScript to enhance its cleanliness and reusability. However, I'm facing quite a challenge in getting it to work seamlessly.
import { DocumentDefinition, FilterQuery, QueryOptions, UpdateQuery } from 'mongoose';
import TaskModel, { TaskDocument } from '../models/Task.model';
import { databaseResponseTimeHistogram } from '../utils/appmetrics';
export async function createTask(
input: DocumentDefinition<
Omit<TaskDocument, 'createdAt' | 'updatedAt' | 'taskId' | 'isCompleted'>
>
) {
const metricsLabels = { operation: 'createTask' };
const timer = databaseResponseTimeHistogram.startTimer();
try {
const result = TaskModel.create(input);
timer({ ...metricsLabels, success: 'true' });
return result;
} catch (err: any) {
timer({ ...metricsLabels, success: 'false' });
throw new Error(err.message);
}
}
export async function findTask(
query: FilterQuery<TaskDocument>,
options: QueryOptions = { lean: true }
) {
const metricsLabels = { operation: 'findTask' };
const timer = databaseResponseTimeHistogram.startTimer();
try {
const result = TaskModel.findOne(query, {}, options);
timer({ ...metricsLabels, success: 'true' });
return result;
} catch (err: any) {
timer({ ...metricsLabels, success: 'false' });
throw new Error(err.message);
}
}
export async function findAndUpdateTask(
query: FilterQuery<TaskDocument>,
update: UpdateQuery<TaskDocument>,
options: QueryOptions
) {
const metricsLabels = { operation: 'findTask' };
const timer = databaseResponseTimeHistogram.startTimer();
try {
const result = TaskModel.findOneAndUpdate(query, update, options);
timer({ ...metricsLabels, success: 'true' });
return result;
} catch (err: any) {
timer({ ...metricsLabels, success: 'false' });
throw new Error(err.message);
}
}
Essentially, my goal is to streamline the metrics functionality by encapsulating the try-catch block into a utility function. This would allow for easy invocation with specific parameters such as the operation, TaskModel.method, and respective arguments like (input) for create, (query, {}, options) for findOne, and (query, update, options) for findManyAndUpdate...
However, I'm encountering difficulties in correctly typing all the various parameters.