HumanReadableLogs.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import LatexLogParser from '../log-parser/latex-log-parser'
  2. import ruleset from './HumanReadableLogsRules'
  3. export default {
  4. parse(rawLog, options) {
  5. const parsedLogEntries =
  6. typeof rawLog === 'string'
  7. ? new LatexLogParser(rawLog, options).parse()
  8. : rawLog
  9. const seenErrorTypes = {} // keep track of types of errors seen
  10. for (const entry of parsedLogEntries.all) {
  11. const ruleDetails = ruleset.find(rule =>
  12. rule.regexToMatch.test(entry.message)
  13. )
  14. if (ruleDetails) {
  15. if (ruleDetails.ruleId) {
  16. entry.ruleId = ruleDetails.ruleId
  17. }
  18. if (ruleDetails.newMessage) {
  19. entry.message = entry.message.replace(
  20. ruleDetails.regexToMatch,
  21. ruleDetails.newMessage
  22. )
  23. }
  24. if (ruleDetails.contentRegex) {
  25. const match = entry.content.match(ruleDetails.contentRegex)
  26. if (match) {
  27. entry.contentDetails = match.slice(1)
  28. }
  29. }
  30. if (entry.contentDetails && ruleDetails.improvedTitle) {
  31. const message = ruleDetails.improvedTitle(
  32. entry.message,
  33. entry.contentDetails
  34. )
  35. if (Array.isArray(message)) {
  36. entry.message = message[0]
  37. // removing the messageComponent, as the markup possible in it was causing crashes when
  38. // attempting to broadcast it in the detach-context (cant structuredClone an html node)
  39. // see https://github.com/overleaf/internal/discussions/15031 for context
  40. // entry.messageComponent = message[1]
  41. } else {
  42. entry.message = message
  43. }
  44. }
  45. if (entry.contentDetails && ruleDetails.highlightCommand) {
  46. entry.command = ruleDetails.highlightCommand(entry.contentDetails)
  47. }
  48. // suppress any entries that are known to cascade from previous error types
  49. if (ruleDetails.cascadesFrom) {
  50. for (const type of ruleDetails.cascadesFrom) {
  51. if (seenErrorTypes[type]) {
  52. entry.suppressed = true
  53. }
  54. }
  55. }
  56. // record the types of errors seen
  57. if (ruleDetails.types) {
  58. for (const type of ruleDetails.types) {
  59. seenErrorTypes[type] = true
  60. }
  61. }
  62. }
  63. }
  64. // filter out the suppressed errors (from the array entries in parsedLogEntries)
  65. for (const [key, errors] of Object.entries(parsedLogEntries)) {
  66. if (typeof errors === 'object' && errors.length > 0) {
  67. parsedLogEntries[key] = Array.from(errors).filter(
  68. err => !err.suppressed
  69. )
  70. }
  71. }
  72. return parsedLogEntries
  73. },
  74. }