mirror of
https://github.com/hexastack/hexabot
synced 2025-04-25 08:50:43 +00:00
Merge pull request #631 from Hexastack/fix/logger-2nd-attempt
Fix/logger 2nd attempt
This commit is contained in:
commit
ad07884fb0
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Hexastack. All rights reserved.
|
* Copyright © 2025 Hexastack. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
@ -127,10 +127,10 @@ export class BotStatsService extends BaseService<BotStats> {
|
|||||||
try {
|
try {
|
||||||
await this.updateOne(insight.id, { value: insight.value + 1 });
|
await this.updateOne(insight.id, { value: insight.value + 1 });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error('Stats hook : Unable to update insight', err);
|
this.logger.error('Unable to update insight', err);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error('Stats hook : Unable to find or create insight', err);
|
this.logger.error('Unable to find or create insight', err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ describe('AttachmentController', () => {
|
|||||||
|
|
||||||
helperService = module.get<HelperService>(HelperService);
|
helperService = module.get<HelperService>(HelperService);
|
||||||
settingService = module.get<SettingService>(SettingService);
|
settingService = module.get<SettingService>(SettingService);
|
||||||
loggerService = module.get<LoggerService>(LoggerService);
|
loggerService = await module.resolve<LoggerService>(LoggerService);
|
||||||
|
|
||||||
helperService.register(
|
helperService.register(
|
||||||
new LocalStorageHelper(settingService, helperService, loggerService),
|
new LocalStorageHelper(settingService, helperService, loggerService),
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Hexastack. All rights reserved.
|
* Copyright © 2025 Hexastack. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
@ -173,7 +173,7 @@ export class MessageController extends BaseController<
|
|||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.debug('MessageController send : Unable to send message', err);
|
this.logger.debug('Unable to send message', err);
|
||||||
throw new BadRequestException(
|
throw new BadRequestException(
|
||||||
'MessageController send : unable to send message',
|
'MessageController send : unable to send message',
|
||||||
);
|
);
|
||||||
|
@ -286,7 +286,7 @@ export class BlockService extends BaseService<
|
|||||||
return e.entity === ev.entity;
|
return e.entity === ev.entity;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn('Block Service : Unknown NLP match type', ev);
|
this.logger.warn('Unknown NLP match type', ev);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Hexastack. All rights reserved.
|
* Copyright © 2025 Hexastack. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
@ -62,10 +62,7 @@ export class BotService {
|
|||||||
context = context || getDefaultConversationContext();
|
context = context || getDefaultConversationContext();
|
||||||
fallback = typeof fallback !== 'undefined' ? fallback : false;
|
fallback = typeof fallback !== 'undefined' ? fallback : false;
|
||||||
const options = block.options;
|
const options = block.options;
|
||||||
this.logger.debug(
|
this.logger.debug('Sending message ... ', event.getSenderForeignId());
|
||||||
'Bot service : Sending message ... ',
|
|
||||||
event.getSenderForeignId(),
|
|
||||||
);
|
|
||||||
// Process message : Replace tokens with context data and then send the message
|
// Process message : Replace tokens with context data and then send the message
|
||||||
const recipient = event.getSender();
|
const recipient = event.getSender();
|
||||||
const envelope = await this.blockService.processMessage(
|
const envelope = await this.blockService.processMessage(
|
||||||
@ -116,7 +113,7 @@ export class BotService {
|
|||||||
assignTo,
|
assignTo,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.logger.debug('Bot service : Assigned labels ', blockLabels);
|
this.logger.debug('Assigned labels ', blockLabels);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,7 +372,7 @@ export class BotService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
this.logger.debug(
|
this.logger.debug(
|
||||||
'Bot service : Started a new conversation with ',
|
'Started a new conversation with ',
|
||||||
subscriber.id,
|
subscriber.id,
|
||||||
block.name,
|
block.name,
|
||||||
);
|
);
|
||||||
@ -386,14 +383,11 @@ export class BotService {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error('Bot service : Unable to store context data!', err);
|
this.logger.error('Unable to store context data!', err);
|
||||||
this.eventEmitter.emit('hook:conversation:end', convo, true);
|
this.eventEmitter.emit('hook:conversation:end', convo, true);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error('Unable to start a new conversation with ', err);
|
||||||
'Botservice : Unable to start a new conversation with ',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Hexastack. All rights reserved.
|
* Copyright © 2025 Hexastack. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
@ -65,10 +65,7 @@ export class MessageService extends BaseService<
|
|||||||
success: true,
|
success: true,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error(
|
this.logger.error('Websocket subscription', e);
|
||||||
'MessageController subscribe : Websocket subscription',
|
|
||||||
e,
|
|
||||||
);
|
|
||||||
throw new InternalServerErrorException(e);
|
throw new InternalServerErrorException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,9 +72,7 @@ export class SubscriberService extends BaseService<
|
|||||||
subscribe: Room.SUBSCRIBER,
|
subscribe: Room.SUBSCRIBER,
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.logger.error(
|
this.logger.error('Websocket subscription');
|
||||||
'SubscriberController subscribe : Websocket subscription',
|
|
||||||
);
|
|
||||||
throw new InternalServerErrorException(e);
|
throw new InternalServerErrorException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
* @returns -
|
* @returns -
|
||||||
*/
|
*/
|
||||||
init(): void {
|
init(): void {
|
||||||
this.logger.debug('Web Channel Handler : initialization ...');
|
this.logger.debug('initialization ...');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,22 +108,17 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.debug(
|
this.logger.debug('WS connected .. sending settings');
|
||||||
'Web Channel Handler : WS connected .. sending settings',
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const menu = await this.menuService.getTree();
|
const menu = await this.menuService.getTree();
|
||||||
return client.emit('settings', { menu, ...settings });
|
return client.emit('settings', { menu, ...settings });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn('Web Channel Handler : Unable to retrieve menu ', err);
|
this.logger.warn('Unable to retrieve menu ', err);
|
||||||
return client.emit('settings', settings);
|
return client.emit('settings', settings);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error('Unable to initiate websocket connection', err);
|
||||||
'Web Channel Handler : Unable to initiate websocket connection',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
client.disconnect();
|
client.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -315,7 +310,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
|
|
||||||
// Check if we have an origin header...
|
// Check if we have an origin header...
|
||||||
if (!req.headers?.origin) {
|
if (!req.headers?.origin) {
|
||||||
this.logger.debug('Web Channel Handler : No origin ', req.headers);
|
this.logger.debug('No origin ', req.headers);
|
||||||
throw new Error('CORS - No origin provided!');
|
throw new Error('CORS - No origin provided!');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,10 +327,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
try {
|
try {
|
||||||
return new URL(origin.trim()).origin;
|
return new URL(origin.trim()).origin;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error(
|
this.logger.error(`Invalid URL in allowed domains: ${origin}`, error);
|
||||||
`Web Channel Handler : Invalid URL in allowed domains: ${origin}`,
|
|
||||||
error,
|
|
||||||
);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -353,10 +345,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
// For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
|
// For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
|
||||||
// interpret as, 'no way Jose.'
|
// interpret as, 'no way Jose.'
|
||||||
res.set('Access-Control-Allow-Origin', '');
|
res.set('Access-Control-Allow-Origin', '');
|
||||||
this.logger.debug(
|
this.logger.debug('No origin found ', req.headers.origin);
|
||||||
'Web Channel Handler : No origin found ',
|
|
||||||
req.headers.origin,
|
|
||||||
);
|
|
||||||
throw new Error('CORS - Domain not allowed!');
|
throw new Error('CORS - Domain not allowed!');
|
||||||
} else {
|
} else {
|
||||||
res.set('Access-Control-Allow-Origin', originUrl.origin);
|
res.set('Access-Control-Allow-Origin', originUrl.origin);
|
||||||
@ -384,10 +373,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
next: (profile: Subscriber) => void,
|
next: (profile: Subscriber) => void,
|
||||||
) {
|
) {
|
||||||
if (!req.session?.web?.profile?.id) {
|
if (!req.session?.web?.profile?.id) {
|
||||||
this.logger.warn(
|
this.logger.warn('No session ID to be found!', req.session);
|
||||||
'Web Channel Handler : No session ID to be found!',
|
|
||||||
req.session,
|
|
||||||
);
|
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.json({ err: 'Web Channel Handler : Unauthorized!' });
|
.json({ err: 'Web Channel Handler : Unauthorized!' });
|
||||||
@ -397,7 +383,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
!Array.isArray(req.session.web.messageQueue)
|
!Array.isArray(req.session.web.messageQueue)
|
||||||
) {
|
) {
|
||||||
this.logger.warn(
|
this.logger.warn(
|
||||||
'Web Channel Handler : Mixed channel request or invalid session data!',
|
'Mixed channel request or invalid session data!',
|
||||||
req.session,
|
req.session,
|
||||||
);
|
);
|
||||||
return res
|
return res
|
||||||
@ -420,10 +406,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
try {
|
try {
|
||||||
await this.validateCors(req, res);
|
await this.validateCors(req, res);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn(
|
this.logger.warn('Attempt to access from an unauthorized origin', err);
|
||||||
'Web Channel Handler : Attempt to access from an unauthorized origin',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
throw new Error('Unauthorized, invalid origin !');
|
throw new Error('Unauthorized, invalid origin !');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,18 +481,14 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
private getMessageQueue(req: Request, res: Response) {
|
private getMessageQueue(req: Request, res: Response) {
|
||||||
// Polling not authorized when using websockets
|
// Polling not authorized when using websockets
|
||||||
if (this.isSocketRequest(req)) {
|
if (this.isSocketRequest(req)) {
|
||||||
this.logger.warn(
|
this.logger.warn('Polling not authorized when using websockets');
|
||||||
'Web Channel Handler : Polling not authorized when using websockets',
|
|
||||||
);
|
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.json({ err: 'Polling not authorized when using websockets' });
|
.json({ err: 'Polling not authorized when using websockets' });
|
||||||
}
|
}
|
||||||
// Session must be active
|
// Session must be active
|
||||||
if (!(req.session && req.session.web && req.session.web.profile.id)) {
|
if (!(req.session && req.session.web && req.session.web.profile.id)) {
|
||||||
this.logger.warn(
|
this.logger.warn('Must be connected to poll messages');
|
||||||
'Web Channel Handler : Must be connected to poll messages',
|
|
||||||
);
|
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.json({ err: 'Polling not authorized : Must be connected' });
|
.json({ err: 'Polling not authorized : Must be connected' });
|
||||||
@ -517,9 +496,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
|
|
||||||
// Can only request polling once at a time
|
// Can only request polling once at a time
|
||||||
if (req.session && req.session.web && req.session.web.polling) {
|
if (req.session && req.session.web && req.session.web.polling) {
|
||||||
this.logger.warn(
|
this.logger.warn('Poll rejected ... already requested');
|
||||||
'Web Channel Handler : Poll rejected ... already requested',
|
|
||||||
);
|
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.json({ err: 'Poll rejected ... already requested' });
|
.json({ err: 'Poll rejected ... already requested' });
|
||||||
@ -543,16 +520,14 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
req.session.web.polling = false;
|
req.session.web.polling = false;
|
||||||
return res.status(200).json(messages.map((msg) => ['message', msg]));
|
return res.status(200).json(messages.map((msg) => ['message', msg]));
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(
|
this.logger.error('Polling failed .. no session data');
|
||||||
'Web Channel Handler : Polling failed .. no session data',
|
|
||||||
);
|
|
||||||
return res.status(500).json({ err: 'No session data' });
|
return res.status(500).json({ err: 'No session data' });
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (req.session.web) {
|
if (req.session.web) {
|
||||||
req.session.web.polling = false;
|
req.session.web.polling = false;
|
||||||
}
|
}
|
||||||
this.logger.error('Web Channel Handler : Polling failed', err);
|
this.logger.error('Polling failed', err);
|
||||||
return res.status(500).json({ err: 'Polling failed' });
|
return res.status(500).json({ err: 'Polling failed' });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -569,11 +544,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
req: Request | SocketRequest,
|
req: Request | SocketRequest,
|
||||||
res: Response | SocketResponse,
|
res: Response | SocketResponse,
|
||||||
) {
|
) {
|
||||||
this.logger.debug(
|
this.logger.debug('subscribe (isSocket=' + this.isSocketRequest(req) + ')');
|
||||||
'Web Channel Handler : subscribe (isSocket=' +
|
|
||||||
this.isSocketRequest(req) +
|
|
||||||
')',
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
const profile = await this.getOrCreateSession(req);
|
const profile = await this.getOrCreateSession(req);
|
||||||
// Join socket room when using websocket
|
// Join socket room when using websocket
|
||||||
@ -581,10 +552,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
try {
|
try {
|
||||||
await req.socket.join(profile.foreign_id);
|
await req.socket.join(profile.foreign_id);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error('Unable to subscribe via websocket', err);
|
||||||
'Web Channel Handler : Unable to subscribe via websocket',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Fetch message history
|
// Fetch message history
|
||||||
@ -595,7 +563,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
const messages = await this.fetchHistory(req, criteria);
|
const messages = await this.fetchHistory(req, criteria);
|
||||||
return res.status(200).json({ profile, messages });
|
return res.status(200).json({ profile, messages });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn('Web Channel Handler : Unable to subscribe ', err);
|
this.logger.warn('Unable to subscribe ', err);
|
||||||
return res.status(500).json({ err: 'Unable to subscribe' });
|
return res.status(500).json({ err: 'Unable to subscribe' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -610,13 +578,13 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
const { type, data } = req.body as Web.IncomingMessage;
|
const { type, data } = req.body as Web.IncomingMessage;
|
||||||
|
|
||||||
if (!req.session?.web?.profile?.id) {
|
if (!req.session?.web?.profile?.id) {
|
||||||
this.logger.debug('Web Channel Handler : No session');
|
this.logger.debug('No session');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if any file is provided
|
// Check if any file is provided
|
||||||
if (type !== 'file' || !('file' in data) || !data.file) {
|
if (type !== 'file' || !('file' in data) || !data.file) {
|
||||||
this.logger.debug('Web Channel Handler : No files provided');
|
this.logger.debug('No files provided');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -636,10 +604,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
createdBy: req.session?.web?.profile?.id,
|
createdBy: req.session?.web?.profile?.id,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error('Unable to store uploaded file', err);
|
||||||
'Web Channel Handler : Unable to store uploaded file',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
throw new Error('Unable to upload file!');
|
throw new Error('Unable to upload file!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -671,10 +636,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
(resolve, reject) => {
|
(resolve, reject) => {
|
||||||
upload(req as Request, res as Response, async (err?: any) => {
|
upload(req as Request, res as Response, async (err?: any) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.logger.error(
|
this.logger.error('Unable to store uploaded file', err);
|
||||||
'Web Channel Handler : Unable to store uploaded file',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
reject(new Error('Unable to upload file!'));
|
reject(new Error('Unable to upload file!'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,7 +651,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
|
|
||||||
// Check if any file is provided
|
// Check if any file is provided
|
||||||
if (!file) {
|
if (!file) {
|
||||||
this.logger.debug('Web Channel Handler : No files provided');
|
this.logger.debug('No files provided');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -703,10 +665,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
createdBy: req.session.web.profile?.id,
|
createdBy: req.session.web.profile?.id,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error('Unable to store uploaded file', err);
|
||||||
'Web Channel Handler : Unable to store uploaded file',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -724,7 +683,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
): Promise<Attachment | null | undefined> {
|
): Promise<Attachment | null | undefined> {
|
||||||
// Check if any file is provided
|
// Check if any file is provided
|
||||||
if (!req.session.web) {
|
if (!req.session.web) {
|
||||||
this.logger.debug('Web Channel Handler : No session provided');
|
this.logger.debug('No session provided');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -784,7 +743,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
): void {
|
): void {
|
||||||
// @TODO: perform payload validation
|
// @TODO: perform payload validation
|
||||||
if (!req.body) {
|
if (!req.body) {
|
||||||
this.logger.debug('Web Channel Handler : Empty body');
|
this.logger.debug('Empty body');
|
||||||
res.status(400).json({ err: 'Web Channel Handler : Bad Request!' });
|
res.status(400).json({ err: 'Web Channel Handler : Bad Request!' });
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
@ -814,10 +773,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn(
|
this.logger.warn('Unable to upload file ', err);
|
||||||
'Web Channel Handler : Unable to upload file ',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.json({ err: 'Web Channel Handler : File upload failed!' });
|
.json({ err: 'Web Channel Handler : File upload failed!' });
|
||||||
@ -849,10 +805,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
if (type) {
|
if (type) {
|
||||||
this.eventEmitter.emit(`hook:chatbot:${type}`, event);
|
this.eventEmitter.emit(`hook:chatbot:${type}`, event);
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(
|
this.logger.error('Webhook received unknown event ', event);
|
||||||
'Web Channel Handler : Webhook received unknown event ',
|
|
||||||
event,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
res.status(200).json(event._adapter.raw);
|
res.status(200).json(event._adapter.raw);
|
||||||
});
|
});
|
||||||
@ -883,9 +836,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
if (!this.isSocketRequest(req) && req.query._get) {
|
if (!this.isSocketRequest(req) && req.query._get) {
|
||||||
switch (req.query._get) {
|
switch (req.query._get) {
|
||||||
case 'settings':
|
case 'settings':
|
||||||
this.logger.debug(
|
this.logger.debug('connected .. sending settings');
|
||||||
'Web Channel Handler : connected .. sending settings',
|
|
||||||
);
|
|
||||||
try {
|
try {
|
||||||
const menu = await this.menuService.getTree();
|
const menu = await this.menuService.getTree();
|
||||||
return res.status(200).json({
|
return res.status(200).json({
|
||||||
@ -894,19 +845,14 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
...settings,
|
...settings,
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn(
|
this.logger.warn('Unable to retrieve menu ', err);
|
||||||
'Web Channel Handler : Unable to retrieve menu ',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
return res.status(500).json({ err: 'Unable to retrieve menu' });
|
return res.status(500).json({ err: 'Unable to retrieve menu' });
|
||||||
}
|
}
|
||||||
case 'polling':
|
case 'polling':
|
||||||
// Handle polling when user is not connected via websocket
|
// Handle polling when user is not connected via websocket
|
||||||
return this.getMessageQueue(req, res as Response);
|
return this.getMessageQueue(req, res as Response);
|
||||||
default:
|
default:
|
||||||
this.logger.error(
|
this.logger.error('Webhook received unknown command');
|
||||||
'Web Channel Handler : Webhook received unknown command',
|
|
||||||
);
|
|
||||||
return res
|
return res
|
||||||
.status(500)
|
.status(500)
|
||||||
.json({ err: 'Webhook received unknown command' });
|
.json({ err: 'Webhook received unknown command' });
|
||||||
@ -923,7 +869,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
return this._handleEvent(req, res);
|
return this._handleEvent(req, res);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.warn('Web Channel Handler : Request check failed', err);
|
this.logger.warn('Request check failed', err);
|
||||||
return res
|
return res
|
||||||
.status(403)
|
.status(403)
|
||||||
.json({ err: 'Web Channel Handler : Unauthorized!' });
|
.json({ err: 'Web Channel Handler : Unauthorized!' });
|
||||||
@ -1131,9 +1077,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
|
|
||||||
// Items count min check
|
// Items count min check
|
||||||
if (!data.length) {
|
if (!data.length) {
|
||||||
this.logger.error(
|
this.logger.error('Unsufficient content count (must be >= 0 for list)');
|
||||||
'Web Channel Handler : Unsufficient content count (must be >= 0 for list)',
|
|
||||||
);
|
|
||||||
throw new Error('Unsufficient content count (list >= 0)');
|
throw new Error('Unsufficient content count (list >= 0)');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1181,7 +1125,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
// Items count min check
|
// Items count min check
|
||||||
if (data.length === 0) {
|
if (data.length === 0) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
'Web Channel Handler : Unsufficient content count (must be > 0 for carousel)',
|
'Unsufficient content count (must be > 0 for carousel)',
|
||||||
);
|
);
|
||||||
throw new Error('Unsufficient content count (carousel > 0)');
|
throw new Error('Unsufficient content count (carousel > 0)');
|
||||||
}
|
}
|
||||||
@ -1293,10 +1237,7 @@ export default abstract class BaseWebChannelHandler<
|
|||||||
await this.sendTypingIndicator(subscriber, timeout);
|
await this.sendTypingIndicator(subscriber, timeout);
|
||||||
return next();
|
return next();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(
|
this.logger.error('Failed in sending typing indicator ', err);
|
||||||
'Web Channel Handler : Failed in sending typing indicator ',
|
|
||||||
err,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
|
|
||||||
import { LoggerService, OnModuleInit } from '@nestjs/common';
|
import { OnModuleInit } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { LoggerService } from '@/logger/logger.service';
|
||||||
import { SettingService } from '@/setting/services/setting.service';
|
import { SettingService } from '@/setting/services/setting.service';
|
||||||
import { Extension } from '@/utils/generics/extension';
|
import { Extension } from '@/utils/generics/extension';
|
||||||
import { HyphenToUnderscore } from '@/utils/types/extension';
|
import { HyphenToUnderscore } from '@/utils/types/extension';
|
||||||
|
@ -1,11 +1,58 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Hexastack. All rights reserved.
|
* Copyright © 2025 Hexastack. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
|
||||||
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
|
||||||
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ConsoleLogger } from '@nestjs/common';
|
import {
|
||||||
|
ConsoleLogger,
|
||||||
|
Inject,
|
||||||
|
Injectable,
|
||||||
|
LogLevel,
|
||||||
|
Scope,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { INQUIRER } from '@nestjs/core';
|
||||||
|
|
||||||
export class LoggerService extends ConsoleLogger {}
|
@Injectable({ scope: Scope.TRANSIENT })
|
||||||
|
export class LoggerService extends ConsoleLogger {
|
||||||
|
constructor(@Inject(INQUIRER) private parentClass: object) {
|
||||||
|
super(parentClass.constructor.name, {
|
||||||
|
logLevels: process.env.NODE_ENV?.includes('dev')
|
||||||
|
? ['log', 'debug', 'error', 'verbose', 'fatal', 'warn']
|
||||||
|
: ['log', 'warn', 'error'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
log(message: string, ...args: any[]) {
|
||||||
|
this.logArguments('log', message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
error(message: string, ...args: any[]) {
|
||||||
|
this.logArguments('error', message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
warn(message: string, ...args: any[]) {
|
||||||
|
this.logArguments('warn', message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(message: string, ...args: any[]) {
|
||||||
|
this.logArguments('debug', message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
verbose(message: string, ...args: any[]) {
|
||||||
|
this.logArguments('verbose', message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
fatal(message: string, ...args: any[]) {
|
||||||
|
this.logArguments('fatal', message, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
private logArguments(type: LogLevel, message: string, args: any[]) {
|
||||||
|
super[type](message);
|
||||||
|
args.forEach((arg) => {
|
||||||
|
super[type](arg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -101,10 +101,11 @@ async function bootstrap() {
|
|||||||
app.useWebSocketAdapter(redisIoAdapter);
|
app.useWebSocketAdapter(redisIoAdapter);
|
||||||
}
|
}
|
||||||
|
|
||||||
process.on('uncaughtException', (error) => {
|
process.on('uncaughtException', async (error) => {
|
||||||
if (error.stack?.toLowerCase().includes('smtp'))
|
if (error.stack?.toLowerCase().includes('smtp')) {
|
||||||
app.get(LoggerService).error('SMTP error', error.stack);
|
const logger = await app.resolve(LoggerService);
|
||||||
else throw error;
|
logger.error('SMTP error', error.stack);
|
||||||
|
} else throw error;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!isProduction) {
|
if (!isProduction) {
|
||||||
|
@ -77,7 +77,7 @@ describe('MigrationService', () => {
|
|||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
service = module.get<MigrationService>(MigrationService);
|
service = module.get<MigrationService>(MigrationService);
|
||||||
loggerService = module.get<LoggerService>(LoggerService);
|
loggerService = await module.resolve<LoggerService>(LoggerService);
|
||||||
metadataService = module.get<MetadataService>(MetadataService);
|
metadataService = module.get<MetadataService>(MetadataService);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ import { UserSeeder } from './user/seeds/user.seed';
|
|||||||
import { userModels } from './user/seeds/user.seed-model';
|
import { userModels } from './user/seeds/user.seed-model';
|
||||||
|
|
||||||
export async function seedDatabase(app: INestApplicationContext) {
|
export async function seedDatabase(app: INestApplicationContext) {
|
||||||
const logger = app.get(LoggerService);
|
const logger = await app.resolve(LoggerService);
|
||||||
const modelSeeder = app.get(ModelSeeder);
|
const modelSeeder = app.get(ModelSeeder);
|
||||||
const categorySeeder = app.get(CategorySeeder);
|
const categorySeeder = app.get(CategorySeeder);
|
||||||
const contextVarSeeder = app.get(ContextVarSeeder);
|
const contextVarSeeder = app.get(ContextVarSeeder);
|
||||||
|
Loading…
Reference in New Issue
Block a user