mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #16253 from overleaf/mj-human-readable-logs-fixes
[web] Fix incorrect error log parsing and imprecise package recommendations GitOrigin-RevId: a0b9c6c51ebf680bb77be88167ab6d35eaa8fa70
This commit is contained in:
parent
c371732e6e
commit
1a6f3fc256
6 changed files with 290 additions and 7 deletions
|
@ -25,6 +25,7 @@ const commandSuggestions = [
|
||||||
['\\href', { name: 'hyperref', command: '\\usepackage{hyperref}' }],
|
['\\href', { name: 'hyperref', command: '\\usepackage{hyperref}' }],
|
||||||
['\\texorpdfstring', { name: 'hyperref', command: '\\usepackage{hyperref}' }],
|
['\\texorpdfstring', { name: 'hyperref', command: '\\usepackage{hyperref}' }],
|
||||||
['\\phantomsection', { name: 'hyperref', command: '\\usepackage{hyperref}' }],
|
['\\phantomsection', { name: 'hyperref', command: '\\usepackage{hyperref}' }],
|
||||||
|
['\\arraybackslash', { name: 'array', command: '\\usepackage{array}' }],
|
||||||
]
|
]
|
||||||
|
|
||||||
const environmentSuggestions = [
|
const environmentSuggestions = [
|
||||||
|
|
|
@ -61,8 +61,8 @@ const rules: Rule[] = [
|
||||||
{
|
{
|
||||||
ruleId: 'hint_undefined_control_sequence',
|
ruleId: 'hint_undefined_control_sequence',
|
||||||
regexToMatch: /Undefined control sequence/,
|
regexToMatch: /Undefined control sequence/,
|
||||||
contentRegex:
|
// Match the last control sequence in the line
|
||||||
/^(?:l\.[0-9]+|<(?:recently read|inserted text|to be read again)>)\s*(\\\S+)/,
|
contentRegex: /^[^\n]*(\\\S+)\s*[\n]/,
|
||||||
improvedTitle: (currentTitle: string, details?: [string]) => {
|
improvedTitle: (currentTitle: string, details?: [string]) => {
|
||||||
if (details?.length && packageSuggestionsForCommands.has(details[0])) {
|
if (details?.length && packageSuggestionsForCommands.has(details[0])) {
|
||||||
const command = details[0]
|
const command = details[0]
|
||||||
|
|
|
@ -74,11 +74,11 @@ export default class LatexParser {
|
||||||
.join('\n')
|
.join('\n')
|
||||||
this.currentError.content += '\n'
|
this.currentError.content += '\n'
|
||||||
this.currentError.content += this.log
|
this.currentError.content += this.log
|
||||||
.linesUpToNextWhitespaceLine()
|
.linesUpToNextWhitespaceLine(true)
|
||||||
.join('\n')
|
.join('\n')
|
||||||
this.currentError.content += '\n'
|
this.currentError.content += '\n'
|
||||||
this.currentError.content += this.log
|
this.currentError.content += this.log
|
||||||
.linesUpToNextWhitespaceLine()
|
.linesUpToNextWhitespaceLine(true)
|
||||||
.join('\n')
|
.join('\n')
|
||||||
this.currentError.raw += this.currentError.content
|
this.currentError.raw += this.currentError.content
|
||||||
const lineNo = this.currentError.raw.match(/l\.([0-9]+)/)
|
const lineNo = this.currentError.raw.match(/l\.([0-9]+)/)
|
||||||
|
@ -372,11 +372,11 @@ class LogText {
|
||||||
this.row--
|
this.row--
|
||||||
}
|
}
|
||||||
|
|
||||||
linesUpToNextWhitespaceLine() {
|
linesUpToNextWhitespaceLine(stopAtError) {
|
||||||
return this.linesUpToNextMatchingLine(/^ *$/)
|
return this.linesUpToNextMatchingLine(/^ *$/, stopAtError)
|
||||||
}
|
}
|
||||||
|
|
||||||
linesUpToNextMatchingLine(match) {
|
linesUpToNextMatchingLine(match, stopAtError) {
|
||||||
const lines = []
|
const lines = []
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -386,6 +386,11 @@ class LogText {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stopAtError && nextLine.match(/^! /)) {
|
||||||
|
this.rewindLine()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
lines.push(nextLine)
|
lines.push(nextLine)
|
||||||
|
|
||||||
if (nextLine.match(match)) {
|
if (nextLine.match(match)) {
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
This is pdfTeX, Version 3.141592653-2.6-1.40.25 (TeX Live 2023) (preloaded format=pdflatex 2023.8.28) 14 DEC 2023 11:46
|
||||||
|
entering extended mode
|
||||||
|
\write18 enabled.
|
||||||
|
%&-line parsing enabled.
|
||||||
|
**main.tex
|
||||||
|
(./main.tex
|
||||||
|
LaTeX2e <2023-06-01> patch level 1
|
||||||
|
L3 programming layer <2023-06-30>
|
||||||
|
(/usr/local/texlive/2023/texmf-dist/tex/latex/base/article.cls
|
||||||
|
Document Class: article 2023/05/17 v1.4n Standard LaTeX document class
|
||||||
|
(/usr/local/texlive/2023/texmf-dist/tex/latex/base/size10.clo
|
||||||
|
File: size10.clo 2023/05/17 v1.4n Standard LaTeX file (size option)
|
||||||
|
)
|
||||||
|
\c@part=\count185
|
||||||
|
\c@section=\count186
|
||||||
|
\c@subsection=\count187
|
||||||
|
\c@subsubsection=\count188
|
||||||
|
\c@paragraph=\count189
|
||||||
|
\c@subparagraph=\count190
|
||||||
|
\c@figure=\count191
|
||||||
|
\c@table=\count192
|
||||||
|
\abovecaptionskip=\skip48
|
||||||
|
\belowcaptionskip=\skip49
|
||||||
|
\bibindent=\dimen140
|
||||||
|
) (/usr/local/texlive/2023/texmf-dist/tex/latex/l3backend/l3backend-pdftex.def
|
||||||
|
File: l3backend-pdftex.def 2023-04-19 L3 backend support: PDF output (pdfTeX)
|
||||||
|
\l__color_backend_stack_int=\count193
|
||||||
|
\l__pdf_internal_box=\box51
|
||||||
|
) (./output.aux)
|
||||||
|
\openout1 = `output.aux'.
|
||||||
|
|
||||||
|
LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
LaTeX Font Info: Checking defaults for TS1/cmr/m/n on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 2.
|
||||||
|
LaTeX Font Info: ... okay on input line 2.
|
||||||
|
! Undefined control sequence.
|
||||||
|
l.3 \foo
|
||||||
|
|
||||||
|
The control sequence at the end of the top line
|
||||||
|
of your error message was never \def'ed. If you have
|
||||||
|
misspelled it (e.g., `\hobx'), type `I' and the correct
|
||||||
|
spelling (e.g., `I\hbox'). Otherwise just continue,
|
||||||
|
and I'll forget about whatever was undefined.
|
||||||
|
|
||||||
|
! Undefined control sequence.
|
||||||
|
l.4 bar \baz
|
||||||
|
|
||||||
|
The control sequence at the end of the top line
|
||||||
|
of your error message was never \def'ed. If you have
|
||||||
|
misspelled it (e.g., `\hobx'), type `I' and the correct
|
||||||
|
spelling (e.g., `I\hbox'). Otherwise just continue,
|
||||||
|
and I'll forget about whatever was undefined.
|
||||||
|
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <7> on input line 5.
|
||||||
|
LaTeX Font Info: External font `cmex10' loaded for size
|
||||||
|
(Font) <5> on input line 5.
|
||||||
|
! Undefined control sequence.
|
||||||
|
<argument> >{\qux
|
||||||
|
}p{2cm}|c
|
||||||
|
l.5 \begin{tabular}{>{\qux}p{2cm}|c}
|
||||||
|
\end{tabular}
|
||||||
|
The control sequence at the end of the top line
|
||||||
|
of your error message was never \def'ed. If you have
|
||||||
|
misspelled it (e.g., `\hobx'), type `I' and the correct
|
||||||
|
spelling (e.g., `I\hbox'). Otherwise just continue,
|
||||||
|
and I'll forget about whatever was undefined.
|
||||||
|
|
||||||
|
|
||||||
|
! LaTeX Error: Illegal character in array arg.
|
||||||
|
|
||||||
|
See the LaTeX manual or LaTeX Companion for explanation.
|
||||||
|
Type H <return> for immediate help.
|
||||||
|
...
|
||||||
|
|
||||||
|
l.5 \begin{tabular}{>{\qux}p{2cm}|c}
|
||||||
|
\end{tabular}
|
||||||
|
You're in trouble here. Try typing <return> to proceed.
|
||||||
|
If that doesn't work, type X <return> to quit.
|
||||||
|
|
||||||
|
|
||||||
|
! LaTeX Error: Illegal character in array arg.
|
||||||
|
|
||||||
|
See the LaTeX manual or LaTeX Companion for explanation.
|
||||||
|
Type H <return> for immediate help.
|
||||||
|
...
|
||||||
|
|
||||||
|
l.5 \begin{tabular}{>{\qux}p{2cm}|c}
|
||||||
|
\end{tabular}
|
||||||
|
You're in trouble here. Try typing <return> to proceed.
|
||||||
|
If that doesn't work, type X <return> to quit.
|
||||||
|
|
||||||
|
! Undefined control sequence.
|
||||||
|
l.6 \url
|
||||||
|
{http://example.com}
|
||||||
|
The control sequence at the end of the top line
|
||||||
|
of your error message was never \def'ed. If you have
|
||||||
|
misspelled it (e.g., `\hobx'), type `I' and the correct
|
||||||
|
spelling (e.g., `I\hbox'). Otherwise just continue,
|
||||||
|
and I'll forget about whatever was undefined.
|
||||||
|
|
||||||
|
! Undefined control sequence.
|
||||||
|
l.7 my \text
|
||||||
|
{foo}
|
||||||
|
The control sequence at the end of the top line
|
||||||
|
of your error message was never \def'ed. If you have
|
||||||
|
misspelled it (e.g., `\hobx'), type `I' and the correct
|
||||||
|
spelling (e.g., `I\hbox'). Otherwise just continue,
|
||||||
|
and I'll forget about whatever was undefined.
|
||||||
|
|
||||||
|
! Undefined control sequence.
|
||||||
|
<argument> >{\arraybackslash
|
||||||
|
}p{2cm}|c
|
||||||
|
l.8 \begin{tabular}{>{\arraybackslash}p{2cm}|c}
|
||||||
|
\end{tabular}
|
||||||
|
The control sequence at the end of the top line
|
||||||
|
of your error message was never \def'ed. If you have
|
||||||
|
misspelled it (e.g., `\hobx'), type `I' and the correct
|
||||||
|
spelling (e.g., `I\hbox'). Otherwise just continue,
|
||||||
|
and I'll forget about whatever was undefined.
|
||||||
|
|
||||||
|
|
||||||
|
! LaTeX Error: Illegal character in array arg.
|
||||||
|
|
||||||
|
See the LaTeX manual or LaTeX Companion for explanation.
|
||||||
|
Type H <return> for immediate help.
|
||||||
|
...
|
||||||
|
|
||||||
|
l.8 \begin{tabular}{>{\arraybackslash}p{2cm}|c}
|
||||||
|
\end{tabular}
|
||||||
|
You're in trouble here. Try typing <return> to proceed.
|
||||||
|
If that doesn't work, type X <return> to quit.
|
||||||
|
|
||||||
|
|
||||||
|
! LaTeX Error: Illegal character in array arg.
|
||||||
|
|
||||||
|
See the LaTeX manual or LaTeX Companion for explanation.
|
||||||
|
Type H <return> for immediate help.
|
||||||
|
...
|
||||||
|
|
||||||
|
l.8 \begin{tabular}{>{\arraybackslash}p{2cm}|c}
|
||||||
|
\end{tabular}
|
||||||
|
You're in trouble here. Try typing <return> to proceed.
|
||||||
|
If that doesn't work, type X <return> to quit.
|
||||||
|
|
||||||
|
[1
|
||||||
|
|
||||||
|
{/usr/local/texlive/2023/texmf-var/fonts/map/pdftex/updmap/pdftex.map}] (./output.aux)
|
||||||
|
***********
|
||||||
|
LaTeX2e <2023-06-01> patch level 1
|
||||||
|
L3 programming layer <2023-06-30>
|
||||||
|
***********
|
||||||
|
)
|
||||||
|
Here is how much of TeX's memory you used:
|
||||||
|
433 strings out of 475237
|
||||||
|
8319 string characters out of 5764570
|
||||||
|
1916244 words of memory out of 5000000
|
||||||
|
21757 multiletter control sequences out of 15000+600000
|
||||||
|
558069 words of font info for 36 fonts, out of 8000000 for 9000
|
||||||
|
1141 hyphenation exceptions out of 8191
|
||||||
|
35i,5n,50p,139b,107s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||||
|
</usr/local/texlive/2023/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb>
|
||||||
|
Output written on output.pdf (1 page, 14417 bytes).
|
||||||
|
PDF statistics:
|
||||||
|
13 PDF objects out of 1000 (max. 8388607)
|
||||||
|
7 compressed objects within 1 object stream
|
||||||
|
0 named destinations out of 1000 (max. 500000)
|
||||||
|
1 words of extra memory for PDF output out of 10000 (max. 10000000)
|
||||||
|
|
|
@ -0,0 +1,81 @@
|
||||||
|
import { expect } from 'chai'
|
||||||
|
import HumanReadableLogs from '../../../../frontend/js/ide/human-readable-logs/HumanReadableLogs'
|
||||||
|
import { readFile } from 'fs/promises'
|
||||||
|
import { join } from 'path'
|
||||||
|
import { some } from 'lodash'
|
||||||
|
|
||||||
|
const fixturePath = '../../helpers/fixtures/logs/'
|
||||||
|
|
||||||
|
async function parse(fixtureName) {
|
||||||
|
const filePath = join(__dirname, fixturePath, fixtureName)
|
||||||
|
const data = await readFile(filePath, 'utf-8', 'r')
|
||||||
|
return HumanReadableLogs.parse(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('HumanReadableLogs', function () {
|
||||||
|
describe('Undefined commands', function () {
|
||||||
|
before(async function () {
|
||||||
|
this.errors = (await parse('undefined-control-sequence.log')).errors
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('For unknown commands', function () {
|
||||||
|
it('Identifies command at beginning of line', function () {
|
||||||
|
expect(
|
||||||
|
some(this.errors, {
|
||||||
|
line: 3,
|
||||||
|
level: 'error',
|
||||||
|
message: 'Undefined control sequence.',
|
||||||
|
})
|
||||||
|
).to.be.true
|
||||||
|
})
|
||||||
|
it('Identifies command at end of line', function () {
|
||||||
|
expect(
|
||||||
|
some(this.errors, {
|
||||||
|
line: 4,
|
||||||
|
level: 'error',
|
||||||
|
message: 'Undefined control sequence.',
|
||||||
|
})
|
||||||
|
).to.be.true
|
||||||
|
})
|
||||||
|
it('Identifies command inside argument', function () {
|
||||||
|
expect(
|
||||||
|
some(this.errors, {
|
||||||
|
line: 5,
|
||||||
|
level: 'error',
|
||||||
|
message: 'Undefined control sequence.',
|
||||||
|
})
|
||||||
|
).to.be.true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('For known commands', function () {
|
||||||
|
it('Identifies command at beginning of line', function () {
|
||||||
|
expect(
|
||||||
|
some(this.errors, {
|
||||||
|
line: 6,
|
||||||
|
level: 'error',
|
||||||
|
message: 'Is \\usepackage{url} missing?',
|
||||||
|
})
|
||||||
|
).to.be.true
|
||||||
|
})
|
||||||
|
it('Identifies command at end of line', function () {
|
||||||
|
expect(
|
||||||
|
some(this.errors, {
|
||||||
|
line: 7,
|
||||||
|
level: 'error',
|
||||||
|
message: 'Is \\usepackage{amsmath} missing?',
|
||||||
|
})
|
||||||
|
).to.be.true
|
||||||
|
})
|
||||||
|
it('Identifies command inside argument', function () {
|
||||||
|
expect(
|
||||||
|
some(this.errors, {
|
||||||
|
line: 8,
|
||||||
|
level: 'error',
|
||||||
|
message: 'Is \\usepackage{array} missing?',
|
||||||
|
})
|
||||||
|
).to.be.true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -400,6 +400,23 @@ describe('logParser', function (done) {
|
||||||
],
|
],
|
||||||
])
|
])
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should parse errors without blank lines between them', function () {
|
||||||
|
const { errors, warnings } = parseLatexLog('undefined-control-sequence.log')
|
||||||
|
expect(warnings).to.be.empty
|
||||||
|
expect(errors.map(x => [x.line, x.message, x.file])).to.deep.equal([
|
||||||
|
[3, 'Undefined control sequence.', './main.tex'],
|
||||||
|
[4, 'Undefined control sequence.', './main.tex'],
|
||||||
|
[5, 'Undefined control sequence.', './main.tex'],
|
||||||
|
[5, 'LaTeX Error: Illegal character in array arg.', './main.tex'],
|
||||||
|
[5, 'LaTeX Error: Illegal character in array arg.', './main.tex'],
|
||||||
|
[6, 'Undefined control sequence.', './main.tex'],
|
||||||
|
[7, 'Undefined control sequence.', './main.tex'],
|
||||||
|
[8, 'Undefined control sequence.', './main.tex'],
|
||||||
|
[8, 'LaTeX Error: Illegal character in array arg.', './main.tex'],
|
||||||
|
[8, 'LaTeX Error: Illegal character in array arg.', './main.tex'],
|
||||||
|
])
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function readLog(filename) {
|
function readLog(filename) {
|
||||||
|
|
Loading…
Reference in a new issue