/**
* Tool Wrapper Utility
* Standardizes error handling and reduces repetitive try-catch blocks
*/
import { getErrorMessage } from "./error.js";
import type { IWordPressClient } from "@/types/client.js";
import type { BaseToolParams } from "@/types/tools.js";
/**
* Wrapper for tool methods that standardizes error handling
*/
export function withErrorHandling<T extends readonly unknown[], R>(
operation: string,
fn: (...args: T) => Promise<R>,
): (...args: T) => Promise<R> {
return async (...args: T): Promise<R> => {
try {
return await fn(...args);
} catch (_error) {
throw new Error(`${operation}: ${getErrorMessage(_error)}`);
}
};
}
/**
* Wrapper for tool methods with validation
*/
export function withValidation<T extends readonly unknown[], R>(
operation: string,
validator: (...args: T) => void,
fn: (...args: T) => Promise<R>,
): (...args: T) => Promise<R> {
return async (...args: T): Promise<R> => {
try {
validator(...args);
return await fn(...args);
} catch (_error) {
throw new Error(`${operation}: ${getErrorMessage(_error)}`);
}
};
}
/**
* Common validation functions
*/
export const validators = {
requireSite: (client: IWordPressClient | null | undefined, params: BaseToolParams) => {
if (!client) {
throw new Error("WordPress client is required");
}
},
requireId: (params: { id?: number | string }) => {
if (!params.id) {
throw new Error("ID parameter is required");
}
},
requireNonEmpty: (value: unknown, fieldName: string) => {
if (!value || (typeof value === "string" && value.trim() === "")) {
throw new Error(`${fieldName} cannot be empty`);
}
},
requireFields: (params: Record<string, unknown>, fields: readonly string[]) => {
for (const field of fields) {
if (params[field] === undefined || params[field] === null) {
throw new Error(`${field} is required`);
}
}
},
};
/**
* Decorator for class methods to add error handling
*/
export function errorHandler(operation: string) {
return function (target: unknown, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function (...args: unknown[]) {
try {
return await originalMethod.apply(this, args);
} catch (_error) {
throw new Error(`${operation}: ${getErrorMessage(_error)}`);
}
};
return descriptor;
};
}
/**
* Helper to format success responses consistently
*/
export function formatSuccessResponse(content: string): string {
return content;
}
/**
* Helper to format error responses consistently
*/
export function formatErrorResponse(operation: string, error: unknown): never {
const message = getErrorMessage(error);
throw new Error(`${operation}: ${message}`);
}
/**
* Simple tool wrapper for standalone async functions
*/
export async function toolWrapper<T>(fn: () => Promise<T>): Promise<T> {
try {
return await fn();
} catch (_error) {
throw new Error(getErrorMessage(_error));
}
}