mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-09 01:49:37 -06:00
Merge pull request #1918 from ricaelchiquetti/main
feat: implement standardized error handling for WhatsApp API responses
This commit is contained in:
commit
827604644b
@ -1,6 +1,7 @@
|
||||
import { RouterBroker } from '@api/abstract/abstract.router';
|
||||
import { NumberDto } from '@api/dto/chat.dto';
|
||||
import { businessController } from '@api/server.module';
|
||||
import { createMetaErrorResponse } from '@utils/errorResponse';
|
||||
import { catalogSchema, collectionsSchema } from '@validate/validate.schema';
|
||||
import { RequestHandler, Router } from 'express';
|
||||
|
||||
@ -11,25 +12,43 @@ export class BusinessRouter extends RouterBroker {
|
||||
super();
|
||||
this.router
|
||||
.post(this.routerPath('getCatalog'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<NumberDto>({
|
||||
request: req,
|
||||
schema: catalogSchema,
|
||||
ClassRef: NumberDto,
|
||||
execute: (instance, data) => businessController.fetchCatalog(instance, data),
|
||||
});
|
||||
try {
|
||||
const response = await this.dataValidate<NumberDto>({
|
||||
request: req,
|
||||
schema: catalogSchema,
|
||||
ClassRef: NumberDto,
|
||||
execute: (instance, data) => businessController.fetchCatalog(instance, data),
|
||||
});
|
||||
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
} catch (error) {
|
||||
// Log error for debugging
|
||||
console.error('Business catalog error:', error);
|
||||
|
||||
// Use utility function to create standardized error response
|
||||
const errorResponse = createMetaErrorResponse(error, 'business_catalog');
|
||||
return res.status(errorResponse.status).json(errorResponse);
|
||||
}
|
||||
})
|
||||
|
||||
.post(this.routerPath('getCollections'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<NumberDto>({
|
||||
request: req,
|
||||
schema: collectionsSchema,
|
||||
ClassRef: NumberDto,
|
||||
execute: (instance, data) => businessController.fetchCollections(instance, data),
|
||||
});
|
||||
try {
|
||||
const response = await this.dataValidate<NumberDto>({
|
||||
request: req,
|
||||
schema: collectionsSchema,
|
||||
ClassRef: NumberDto,
|
||||
execute: (instance, data) => businessController.fetchCollections(instance, data),
|
||||
});
|
||||
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
return res.status(HttpStatus.OK).json(response);
|
||||
} catch (error) {
|
||||
// Log error for debugging
|
||||
console.error('Business collections error:', error);
|
||||
|
||||
// Use utility function to create standardized error response
|
||||
const errorResponse = createMetaErrorResponse(error, 'business_collections');
|
||||
return res.status(errorResponse.status).json(errorResponse);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ import { InstanceDto } from '@api/dto/instance.dto';
|
||||
import { TemplateDto } from '@api/dto/template.dto';
|
||||
import { templateController } from '@api/server.module';
|
||||
import { ConfigService } from '@config/env.config';
|
||||
import { createMetaErrorResponse } from '@utils/errorResponse';
|
||||
import { instanceSchema, templateSchema } from '@validate/validate.schema';
|
||||
import { RequestHandler, Router } from 'express';
|
||||
|
||||
@ -16,24 +17,42 @@ export class TemplateRouter extends RouterBroker {
|
||||
super();
|
||||
this.router
|
||||
.post(this.routerPath('create'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<TemplateDto>({
|
||||
request: req,
|
||||
schema: templateSchema,
|
||||
ClassRef: TemplateDto,
|
||||
execute: (instance, data) => templateController.createTemplate(instance, data),
|
||||
});
|
||||
try {
|
||||
const response = await this.dataValidate<TemplateDto>({
|
||||
request: req,
|
||||
schema: templateSchema,
|
||||
ClassRef: TemplateDto,
|
||||
execute: (instance, data) => templateController.createTemplate(instance, data),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.CREATED).json(response);
|
||||
res.status(HttpStatus.CREATED).json(response);
|
||||
} catch (error) {
|
||||
// Log error for debugging
|
||||
console.error('Template creation error:', error);
|
||||
|
||||
// Use utility function to create standardized error response
|
||||
const errorResponse = createMetaErrorResponse(error, 'template_creation');
|
||||
res.status(errorResponse.status).json(errorResponse);
|
||||
}
|
||||
})
|
||||
.get(this.routerPath('find'), ...guards, async (req, res) => {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: instanceSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance) => templateController.findTemplate(instance),
|
||||
});
|
||||
try {
|
||||
const response = await this.dataValidate<InstanceDto>({
|
||||
request: req,
|
||||
schema: instanceSchema,
|
||||
ClassRef: InstanceDto,
|
||||
execute: (instance) => templateController.findTemplate(instance),
|
||||
});
|
||||
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
res.status(HttpStatus.OK).json(response);
|
||||
} catch (error) {
|
||||
// Log error for debugging
|
||||
console.error('Template find error:', error);
|
||||
|
||||
// Use utility function to create standardized error response
|
||||
const errorResponse = createMetaErrorResponse(error, 'template_find');
|
||||
res.status(errorResponse.status).json(errorResponse);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -60,6 +60,13 @@ export class TemplateService {
|
||||
const response = await this.requestTemplate(postData, 'POST');
|
||||
|
||||
if (!response || response.error) {
|
||||
// If there's an error from WhatsApp API, throw it with the real error data
|
||||
if (response && response.error) {
|
||||
// Create an error object that includes the template field for Meta errors
|
||||
const metaError = new Error(response.error.message || 'WhatsApp API Error');
|
||||
(metaError as any).template = response.error;
|
||||
throw metaError;
|
||||
}
|
||||
throw new Error('Error to create template');
|
||||
}
|
||||
|
||||
@ -75,8 +82,9 @@ export class TemplateService {
|
||||
|
||||
return template;
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
throw new Error('Error to create template');
|
||||
this.logger.error('Error in create template: ' + error);
|
||||
// Propagate the real error instead of "engolindo" it
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@ -86,6 +94,7 @@ export class TemplateService {
|
||||
const version = this.configService.get<WaBusiness>('WA_BUSINESS').VERSION;
|
||||
urlServer = `${urlServer}/${version}/${this.businessId}/message_templates`;
|
||||
const headers = { 'Content-Type': 'application/json', Authorization: `Bearer ${this.token}` };
|
||||
|
||||
if (method === 'GET') {
|
||||
const result = await axios.get(urlServer, { headers });
|
||||
return result.data;
|
||||
@ -94,8 +103,17 @@ export class TemplateService {
|
||||
return result.data;
|
||||
}
|
||||
} catch (e) {
|
||||
this.logger.error(e.response.data);
|
||||
return e.response.data.error;
|
||||
this.logger.error(
|
||||
'WhatsApp API request error: ' + (e.response?.data ? JSON.stringify(e.response?.data) : e.message),
|
||||
);
|
||||
|
||||
// Return the complete error response from WhatsApp API
|
||||
if (e.response?.data) {
|
||||
return e.response.data;
|
||||
}
|
||||
|
||||
// If no response data, throw connection error
|
||||
throw new Error(`Connection error: ${e.message}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
47
src/utils/errorResponse.ts
Normal file
47
src/utils/errorResponse.ts
Normal file
@ -0,0 +1,47 @@
|
||||
import { HttpStatus } from '@api/routes/index.router';
|
||||
|
||||
export interface MetaErrorResponse {
|
||||
status: number;
|
||||
error: string;
|
||||
message: string;
|
||||
details: {
|
||||
whatsapp_error: string;
|
||||
whatsapp_code: string | number;
|
||||
error_user_title: string;
|
||||
error_user_msg: string;
|
||||
error_type: string;
|
||||
error_subcode: number | null;
|
||||
fbtrace_id: string | null;
|
||||
context: string;
|
||||
type: string;
|
||||
};
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates standardized error response for Meta/WhatsApp API errors
|
||||
*/
|
||||
export function createMetaErrorResponse(error: any, context: string): MetaErrorResponse {
|
||||
// Extract Meta/WhatsApp specific error fields
|
||||
const metaError = error.template || error;
|
||||
const errorUserTitle = metaError.error_user_title || metaError.message || 'Unknown error';
|
||||
const errorUserMsg = metaError.error_user_msg || metaError.message || 'Unknown error';
|
||||
|
||||
return {
|
||||
status: HttpStatus.BAD_REQUEST,
|
||||
error: 'Bad Request',
|
||||
message: errorUserTitle,
|
||||
details: {
|
||||
whatsapp_error: errorUserMsg,
|
||||
whatsapp_code: metaError.code || 'UNKNOWN_ERROR',
|
||||
error_user_title: errorUserTitle,
|
||||
error_user_msg: errorUserMsg,
|
||||
error_type: metaError.type || 'UNKNOWN',
|
||||
error_subcode: metaError.error_subcode || null,
|
||||
fbtrace_id: metaError.fbtrace_id || null,
|
||||
context,
|
||||
type: 'whatsapp_api_error',
|
||||
},
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user