Files
MinglarBackendNestJS/src/common/utils/handlers/safeHandler.ts
paritosh18 82cbaddce1 feat: add serverless-offline plugin and new showSuggestion function
- Added serverless-offline plugin to package.json and serverless.yml for local development.
- Implemented new showSuggestion function in host.yml with appropriate memory size and event configuration.
- Removed deprecated getSuggestion function from minglaradmin.yml and updated related handlers.
- Enhanced safeHandler to convert Prisma errors to ApiError automatically, improving error handling.
- Introduced comprehensive Prisma error handling in ApiError.ts, mapping error codes to user-friendly messages and HTTP status codes.
2025-11-28 15:33:43 +05:30

124 lines
3.6 KiB
TypeScript

// safeHandler.ts
import { APIGatewayProxyEvent, Context, APIGatewayProxyResult } from 'aws-lambda';
import ApiError from '../helper/ApiError';
export const safeHandler = (
handler: (event: APIGatewayProxyEvent, context?: Context) => Promise<APIGatewayProxyResult | any>
): ((event: APIGatewayProxyEvent, context: Context) => Promise<APIGatewayProxyResult>) => {
return async (event, context) => {
try {
const result = await handler(event, context);
// If handler returned null/undefined → return 204 response
if (!result) {
return {
statusCode: 204,
body: JSON.stringify({
success: true,
statusCode: 204,
message: 'No content',
data: null,
}),
};
}
// If handler returned a structured Lambda response
if (result.statusCode && result.body) {
return {
statusCode: result.statusCode,
headers: result.headers || {},
body: injectStatusCodeIntoBody(result.body, result.statusCode),
};
}
// If handler returned plain data (not wrapped)
return {
statusCode: 200,
body: JSON.stringify({
success: true,
message: 'OK',
statusCode: 200,
data: result,
}),
};
} catch (error: any) {
console.error('❌ Error occurred:', error);
// Convert Prisma errors to ApiError automatically
if (ApiError.isPrismaError(error)) {
const apiError = ApiError.fromPrismaError(error);
return {
statusCode: apiError.statusCode,
body: JSON.stringify({
success: false,
message: apiError.message,
statusCode: apiError.statusCode,
data: null,
error: {
code: apiError.code || apiError.statusCode,
description: apiError.message,
statusCode: apiError.statusCode,
...(apiError.meta && { meta: apiError.meta }),
...(process.env.STAGE !== 'prod' && { debug: apiError.stack }),
},
}),
};
}
if (error instanceof ApiError) {
return {
statusCode: error.statusCode,
body: JSON.stringify({
success: false,
message: error.message,
statusCode: error.statusCode,
data: null,
error: {
code: error.code || error.statusCode,
description: error.message,
statusCode: error.statusCode,
...(error.meta && { meta: error.meta }),
...(process.env.STAGE !== 'prod' && { debug: error.stack }),
},
}),
};
}
// Internal Server Error fallback
return {
statusCode: 500,
body: JSON.stringify({
success: false,
message: 'Internal server error',
statusCode: 500,
data: null,
error: {
code: 500,
description: 'Internal server error',
statusCode: 500,
...(process.env.STAGE !== 'prod' && { debug: error.stack }),
},
}),
};
}
};
};
// Utility: safely inject statusCode into the JSON response body
function injectStatusCodeIntoBody(body: string, statusCode: number): string {
try {
const json = JSON.parse(body);
json.statusCode = statusCode;
return JSON.stringify(json);
} catch {
// If body is not JSON, wrap it
return JSON.stringify({
success: true,
statusCode,
message: body,
data: null,
});
}
}