5htp-core 0.6.0-8 → 0.6.0-82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -55,11 +55,13 @@ export type ServerBug = {
55
55
  },
56
56
 
57
57
  // Error
58
- error: Error,
59
- stacktrace: string,
60
- logs: TJsonLog[],
58
+ title?: string,
59
+ stacktraces: string[],
60
+ context: object[],
61
61
  }
62
62
 
63
+ export type TCatchedError = Error | CoreError | Anomaly;
64
+
63
65
  /*----------------------------------
64
66
  - ERREURS
65
67
  ----------------------------------*/
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.6.0-8",
4
+ "version": "0.6.0-82",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -17,7 +17,7 @@ import Ansi2Html from 'ansi-to-html';
17
17
  // Core libs
18
18
  import type ApplicationContainer from '..';
19
19
  import context from '@server/context';
20
- import type { ServerBug, Anomaly, CoreError } from '@common/errors';
20
+ import type { ServerBug, TCatchedError, CoreError } from '@common/errors';
21
21
  import type ServerRequest from '@server/services/router/request';
22
22
  import { SqlError } from '@server/services/database/debug';
23
23
 
@@ -99,8 +99,6 @@ export type TJsonLog = {
99
99
 
100
100
  const LogPrefix = '[console]'
101
101
 
102
- const errorMailInterval = (1 * 60 * 60 * 1000); // 1 hour
103
-
104
102
  const logLevels = {
105
103
  'log': 0,
106
104
  'info': 3,
@@ -144,13 +142,6 @@ export default class Console {
144
142
  public logger!: Logger<ILogObj>;
145
143
  // Buffers
146
144
  public logs: TJsonLog[] = [];
147
- // Bug ID => Timestamp latest send
148
- private sentBugs: {[bugId: string]: number} = {};
149
-
150
- // Old (still useful???)
151
- /*public clients: TGuestLogs[] = [];
152
- public requests: TRequestLogs[] = [];
153
- public sqlQueries: TDbQueryLog[] = [];*/
154
145
 
155
146
  /*----------------------------------
156
147
  - LIFECYCLE
@@ -283,11 +274,9 @@ export default class Console {
283
274
  this.logs = this.logs.slice(bufferOverflow);
284
275
  }
285
276
 
286
- public async createBugReport( error: Error | CoreError | Anomaly, request?: ServerRequest ) {
277
+ // We don't prevent duplicates because we want to receive all variants of the same error
278
+ public async createBugReport( error: TCatchedError, request?: ServerRequest ) {
287
279
 
288
- // Print error
289
- const originalError = ('originalError' in error && error.originalError) ? error.originalError : error;
290
- this.logger.error(LogPrefix, `Sending bug report for the following error:`, error, originalError);
291
280
  /*const youchRes = new Youch(error, {});
292
281
  const jsonResponse = await youchRes.toJSON()
293
282
  console.log( forTerminal(jsonResponse, {
@@ -314,28 +303,6 @@ export default class Console {
314
303
  if (application === undefined)
315
304
  return console.error(LogPrefix, "Can't send bug report because the application is not instanciated");
316
305
 
317
- // Print the error so it's accessible via logs
318
- if (error instanceof SqlError) {
319
- let printedQuery: string;
320
- try {
321
- printedQuery = this.printSql( error.query );
322
- } catch (error) {
323
- printedQuery = 'Failed to print query:' + (error || 'unknown error');
324
- }
325
- console.error(`Error caused by this query:`, printedQuery);
326
- }
327
-
328
- if (('dataForDebugging' in error) && error.dataForDebugging !== undefined)
329
- console.error(LogPrefix, `More data about the error:`, error.dataForDebugging);
330
-
331
- // Prevent spamming the mailbox if infinite loop
332
- const bugId = ['server', request?.user?.name, undefined, error.message].filter(e => !!e).join('::');
333
- const lastSending = this.sentBugs[bugId];
334
- this.sentBugs[bugId] = Date.now();
335
- const shouldSendReport = lastSending === undefined || lastSending < Date.now() - errorMailInterval;
336
- if (!shouldSendReport)
337
- return;
338
-
339
306
  // Get context
340
307
  const now = new Date();
341
308
  const hash = uuid();
@@ -343,7 +310,43 @@ export default class Console {
343
310
 
344
311
  // On envoi l'email avant l'insertion dans bla bdd
345
312
  // Car cette denrière a plus de chances de provoquer une erreur
346
- const logs = this.logs.filter(e => e.channel.channelId === channelId).slice(-100);
313
+ //const logs = this.logs.filter(e => e.channel.channelId === channelId).slice(-100);
314
+ const stacktraces: string[] = [];
315
+ const context: object[] = [];
316
+
317
+ let currentError: TCatchedError | undefined = error;
318
+ let title: string | undefined;
319
+ while (currentError !== undefined) {
320
+
321
+ if (title === undefined)
322
+ title = currentError.message;
323
+
324
+ // Stacktrace
325
+ this.logger.error(LogPrefix, `Sending bug report for the following error:`, currentError);
326
+ stacktraces.push(currentError.stack || currentError.message);
327
+
328
+ // Context
329
+ if (('dataForDebugging' in currentError) && currentError.dataForDebugging !== undefined) {
330
+ console.error(LogPrefix, `More data about the error:`, currentError.dataForDebugging);
331
+ context.push(currentError.dataForDebugging || {});
332
+ }
333
+
334
+ // Print the error so it's accessible via logs
335
+ if (currentError instanceof SqlError) {
336
+ let printedQuery: string;
337
+ try {
338
+ printedQuery = this.printSql( currentError.query );
339
+ } catch (error) {
340
+ printedQuery = 'Failed to print query:' + (error || 'unknown error');
341
+ }
342
+ console.error(`Error caused by this query:`, printedQuery);
343
+ }
344
+
345
+ // Go deeper
346
+ currentError = 'originalError' in currentError
347
+ ? currentError.originalError
348
+ : undefined
349
+ }
347
350
 
348
351
  const bugReport: ServerBug = {
349
352
 
@@ -372,9 +375,9 @@ export default class Console {
372
375
  } : {}),
373
376
 
374
377
  // Error
375
- error: originalError,
376
- stacktrace: (originalError.stack || originalError.message || error.stack || error.message) as string,
377
- logs
378
+ title,
379
+ stacktraces,
380
+ context
378
381
  }
379
382
 
380
383
  await application.runHook('bug', bugReport);
@@ -392,12 +395,23 @@ export default class Console {
392
395
  ----------------------------------*/
393
396
 
394
397
  public bugToHtml( report: ServerBug ) {
398
+
395
399
  return `
396
400
  <b>Channel</b>: ${report.channelType} (${report.channelId})<br />
397
401
  <b>User</b>: ${report.user ? (report.user.name + ' (' + report.user.email + ')') : 'Unknown'}<br />
398
402
  <b>IP</b>: ${report.ip}<br />
399
- <b>Error</b>: ${report.error.message}<br />
400
- ${this.printHtml(report.stacktrace)}<br />
403
+
404
+ ${report.stacktraces.map((stacktrace, index) => `
405
+ <hr />
406
+ <b>Error ${index + 1}</b>:
407
+ ${this.printHtml(stacktrace)}<br />
408
+ `).join('')}
409
+
410
+ ${report.context.map((context, index) => `
411
+ <hr />
412
+ <b>Context ${index + 1}</b>: ${this.jsonToHTML(context)}<br />
413
+ `).join('')}
414
+
401
415
  ${report.request ? `
402
416
  <hr />
403
417
  <b>Request</b>: ${report.request.method} ${report.request.url}<br />
@@ -433,7 +447,7 @@ Logs: ${this.config.enable ? `<br/>` + this.logsToHTML(report.logs) : 'Logs coll
433
447
  });
434
448
 
435
449
  // Print args as ANSI
436
- const logArgsAndErrorsMarkup = this.logger.runtime.prettyFormatLogObj(log.args, this.logger.settings);
450
+ const logArgsAndErrorsMarkup = this.logger["runtime"].prettyFormatLogObj(log.args, this.logger.settings);
437
451
  const logErrors = logArgsAndErrorsMarkup.errors;
438
452
  const logArgs = logArgsAndErrorsMarkup.args;
439
453
  const logErrorsStr = (logErrors.length > 0 && logArgs.length > 0 ? "\n" : "") + logErrors.join("\n");
package/types/icons.d.ts CHANGED
@@ -1 +1 @@
1
- export type TIcones = "times"|"solid/spinner-third"|"long-arrow-right"|"sack-dollar"|"bell"|"bullseye"|"project-diagram"|"user-friends"|"eye"|"lock"|"comments"|"phone"|"chalkboard-teacher"|"rocket"|"user-circle"|"chart-bar"|"crosshairs"|"plus-circle"|"comments-alt"|"user-shield"|"shield-alt"|"chart-line"|"money-bill-wave"|"star"|"link"|"file-alt"|"long-arrow-left"|"arrow-right"|"at"|"calendar-alt"|"paper-plane"|"search"|"lightbulb"|"magnet"|"brands/linkedin"|"user-plus"|"mouse-pointer"|"thumbs-up"|"dollar-sign"|"key"|"user"|"solid/crown"|"brands/discord"|"pen"|"plus"|"file"|"envelope"|"angle-up"|"angle-down"|"clock"|"cog"|"trash"|"ellipsis-h"|"binoculars"|"times-circle"|"coins"|"download"|"angle-right"|"info-circle"|"check-circle"|"exclamation-circle"|"check"|"meh-rolling-eyes"|"arrow-left"|"bars"|"users"|"bug"|"solid/star"|"solid/star-half-alt"|"regular/star"|"chevron-left"|"power-off"|"play"|"minus-circle"|"external-link"|"question-circle"|"plane-departure"|"brands/whatsapp"|"wind"|"arrow-to-bottom"|"map-marker-alt"|"exclamation-triangle"|"solid/check-circle"|"solid/exclamation-triangle"|"solid/times-circle"|"broom"|"minus"|"comment-alt"|"briefcase"|"map-marker"|"fire"|"solid/magic"|"industry"|"calendar"|"globe"|"magic"|"coin"|"building"|"graduation-cap"|"bold"|"italic"|"underline"|"strikethrough"|"subscript"|"superscript"|"code"|"unlink"|"font"|"empty-set"|"horizontal-rule"|"page-break"|"image"|"table"|"poll"|"columns"|"sticky-note"|"caret-right"|"align-left"|"align-center"|"align-right"|"align-justify"|"indent"|"outdent"|"list-ul"|"check-square"|"h1"|"h2"|"h3"|"h4"|"list-ol"|"paragraph"|"quote-left"
1
+ export type TIcones = "times"|"solid/spinner-third"|"long-arrow-right"|"sack-dollar"|"bell"|"bullseye"|"project-diagram"|"user-friends"|"eye"|"lock"|"comments"|"phone"|"chalkboard-teacher"|"rocket"|"chart-bar"|"user-circle"|"crosshairs"|"plus-circle"|"comments-alt"|"arrow-right"|"link"|"key"|"user"|"at"|"user-shield"|"shield-alt"|"chart-line"|"money-bill-wave"|"star"|"file-alt"|"long-arrow-left"|"user-plus"|"mouse-pointer"|"thumbs-up"|"dollar-sign"|"calendar-alt"|"paper-plane"|"brands/linkedin"|"search"|"lightbulb"|"magnet"|"angle-up"|"angle-down"|"solid/crown"|"brands/discord"|"pen"|"plus"|"file"|"envelope"|"clock"|"cog"|"trash"|"ellipsis-h"|"binoculars"|"coins"|"times-circle"|"download"|"info-circle"|"check-circle"|"exclamation-circle"|"check"|"meh-rolling-eyes"|"arrow-left"|"bars"|"solid/star"|"solid/star-half-alt"|"regular/star"|"chevron-left"|"power-off"|"play"|"minus-circle"|"external-link"|"question-circle"|"plane-departure"|"brands/whatsapp"|"wind"|"map-marker-alt"|"arrow-to-bottom"|"users"|"bug"|"broom"|"solid/check-circle"|"solid/exclamation-triangle"|"solid/times-circle"|"minus"|"solid/magic"|"exclamation-triangle"|"industry"|"map-marker"|"calendar"|"briefcase"|"fire"|"magic"|"globe"|"comment-alt"|"coin"|"building"|"graduation-cap"|"unlink"|"bold"|"italic"|"underline"|"strikethrough"|"subscript"|"superscript"|"code"|"font"|"empty-set"|"horizontal-rule"|"page-break"|"image"|"table"|"poll"|"columns"|"sticky-note"|"caret-right"|"align-left"|"align-center"|"align-right"|"align-justify"|"indent"|"outdent"|"list-ul"|"check-square"|"h1"|"h2"|"h3"|"h4"|"list-ol"|"paragraph"|"quote-left"