6

I have this very short TeX file

\documentclass[12pt]{report}
\usepackage[a4paper,widh=100mm,top=50mm]{geometry}
\begin{document}
test
\end{document}

in which I have made an mistake writing widh instead of width. Now when I compile via pdflatex I would expect something like

! Error message: blablabala
l.2 \usepackage[a4paper,widh=100mm,top=50mm]{geometry}

which would help me spot the line in which the error originated in my source file (that would be the second line).

But instead I receive this error message

! Package keyval Error: widh undefined.

See the keyval package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.994 \ProcessOptionsKV[p]{Gm}

Why so? Furthermore how is it supposed to be helpful to , not only not show the line in which the error occurred, but even to show a different line in a different file, which?

My take on it is that l.994 \ProcessOptionsKV[p]{Gm} is some codepart that was called with my data from line 2 and the error only occured then and that it fine, but why then would the message not in addition state the file and a backtrack / trace to the actual line?

update to clarify the issue

I made some more testing and adapted the tex source to this

\documentclass[12pt]{report}
\usepackage[a4paper,widh=100mm,top=50mm]{geometry}
\errmessage{line three intentionally throws an error}
\begin{document}
\end{document}

which on purpose throws an error in the third line and the output shows then

/usr/share/texmf-dist/tex/latex/geometry/geometry.sty:994: Package keyval Error
: widh undefined.

See the keyval package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.994 \ProcessOptionsKV[p]{Gm}
                              %
)
./testerrorlinemadness.tex:3: line three intentionally throws an error.
l.3 ...e{line three intentionally throws an error}

clearly making the point that when raising the first error my source text file had not yet evaluated the third line and hence has imho no real excuse to **not to feature the current line number at occurrence of error*.

Update, how would other languages handle error messages?

Since the comments and answers had a tendency to argue that it is completely natural and acceptable that the example feature would not report the more correct line number (the line where the error was provoked in the original tex file) I would like to show that other languages can indeed give a trace back to the point where the error occured.

To do so lets have a look at a short example how javascript would have handled a comparable error reporting task

// EXAMPLE how error message and propagation work in many another
// language (example javascript)
//
// description: what would be MACROS in latex such as /usepackage 
// would be named FUNCTIONS in javascript. 
// To keep with the example in latex and allow comparison 
// we make up a two functions 1: "usepackage" and 2: "geometry"

function usepackage(parameter)
{
  geometry(parameter); 
}

function geometry(parameter)
{
  ProcessOptionsKV=parameter.width.length;
}


// When now calling the usepackage correctly no error occurs 
usepackage( {width:"12mm"} )

// But when providing wrong input, there is an error message
usepackage( {widh:"12mm"} )

// this is the error message
/*
Exception: TypeError: parameter.width is undefined
geometry@Scratchpad/1:16:3
usepackage@Scratchpad/1:11:3
@Scratchpad/1:24:1
*/
// reading the message shows backtracingly line by line
// how the error came about. after the Error message it shows that
// the error occured in 
// 1. function "geometry" in file "Scratchpad/1" line 16,
// which was called from 
// 2. function "usepackage" in file "Scratchpad/1" line 11 
// which was provided with the wrong input from 
// 3. the file "Scratchpad/1" line 24
//
  • 1
    Well, it does say "widh undefined" and widh happens once in your document... – auden Aug 12 '16 at 20:09
  • You could run pdftex with the -file-line-error option (see, e.g., man pdftex). Edit: Also note that latex.ltx sets \errorcontextlines=-1; you could also reset that parameter. – GuM Aug 12 '16 at 20:13
  • @heather smart ! But consider that this was purposively an short and simple example in which tracing of a word is easy. misspelling it to with in combination with some english text would not allow to spot that easily. My easy example is no real excuse or explanation why the error is not reported as I suggest, is it? – humanityANDpeace Aug 12 '16 at 20:47
  • @GustavoMezzetti what to you mean by latex.ltx and the \errorcontextlines=-1? – humanityANDpeace Aug 12 '16 at 20:48
  • why do you think TeX has any information as to where wdth was initially entered? It shows all the information it has at the point that an error is first encountered, which is when the keys are processed with \ProcessOptionsKV – David Carlisle Aug 12 '16 at 20:56
  • 2
    When it issues an error, TeX typically has many input sources pending, more or less equivalent to a stack of pending procedure calls. The \errorcontextlines parameter tells how many of these pending levels should be displayed to the user when an error occurs. The LaTeX format, of which latex.ltx is the source code, sets this number to -1 (no intermediate level is displayed), because its authors felt the user would have been shocked by the sight of LaTeX’s internal macros… (;-) – GuM Aug 12 '16 at 21:04
  • if your main document had \input{chapter2} on line 5 and you had an error on line 100 of chapter 2, you seem to be arguing that tex should report the error as line 5 not line 100?? (at this level there is no difference from using a package and having an error on line 994 and inputting a chapter and having an error on line 100) – David Carlisle Aug 12 '16 at 21:11
  • @DavidCarlisle at the point when \ProcessOptionsKV finally result in an error, pdflatex has digressed (potentially executing several functions). Now it would make sense that either at each digression the necessary information is forwared, or that upon an error, the whole stack is presented as to allow a user to see the actual code line where it occured. Look at the addition I made to the question. It is apparent that pdflatex continues after the strange error at line 3. Hence if the error would have been signalled all the way up it should have been possible to tell that it was in line 2 – humanityANDpeace Aug 12 '16 at 21:11
  • lots of things could be different, but certainly that information is not exposed by Tex, so there is no way any latex package can do this. remember you are using a macro processing language designed with the memory constraints of the 1970's in mind. Lots of things that could, in principle, have been stuck on a stack in case they might be used are discarded.... – David Carlisle Aug 12 '16 at 21:15
  • Note, however, that in this case increasing \errorcontextlines does not produce the information you are asking for. The reason is that you are (comprehensibly!) misunderstanding how TeX behaves in this case. From TeX’s point of view, line 2 of your source file contains no error at all: it just asks to load a certain file and to pass it certain—as it were—“command line arguments”. Only the loaded file knows how to interpret those arguments and, when it detects that one of them is meaningless, throws an error. – GuM Aug 12 '16 at 21:15
  • 1
    @GustavoMezzetti at the point of the error tex does internally have a stack of open files and a file pointer to each of them so the OP is arguably correct that in some hypothetical system this stack could be exposed rather than just the line number of the most recently opened file, but it doesn't so that's that:-) – David Carlisle Aug 12 '16 at 21:18
  • @DavidCarlisle: I know that; but even if TeX were to change its rules and display all pending input sources at the time an error occurs, I am not sure if this would actually be helpful or, rather, a source of confusion. I think that the assessment made by a human about which file contains the “actual” source of the error is sometimes very subtle, and difficult for a machine to emulate. – GuM Aug 12 '16 at 21:26
  • @GustavoMezzetti no argument from me:-) – David Carlisle Aug 12 '16 at 21:27
  • This is rapidly evolving towards an opinion-based question… – GuM Aug 12 '16 at 22:36
  • @GustavoMezzetti Not really sure, there is the actual problem shown in an factual example. http://tex.stackexchange.com/questions/125399/how-to-trace-latex-errors-efficiently shows that getting enough information from error messages is something latex might have an actual problem. ** I also accepted Davids answer** as it tells that there is no way in the pdflatex compiler to get more information (i.e. a stacktrace), which puts information to the question – humanityANDpeace Aug 12 '16 at 22:41
  • 1
    See section 311 (show_context) in the source code of TeX (texdoc tex). It has a condition (name>17) to stop when the first "external" file is reached, among lines in the input stack. This made sense for Knuth given the way he imagined TeX being used. I can confirm that if I recompile TeX without that first condition (NOTE: if you change TeX you should rename it), then I indeed see line number from the original file: but it's going to be on line 3: the first token after the \usepackage ends (error or not). (Example.) – ShreevatsaR May 25 '17 at 16:47

2 Answers2

4

If you want a more informative error message you can increase \errorcontextlines

\errorcontextlines=200
\documentclass[12pt]{report}
\usepackage[a4paper,widh=100mm,top=50mm]{geometry}
\begin{document}
test
\end{document}

produces

! Package keyval Error: widh undefined.

See the keyval package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

\GenericError  ...                                
                                                  \endgroup 
\KV@split ...x \KV@errx {\@tempa \space undefined}
                                                  \else \ifx \@empty #3\@emp...

\KV@do ...ax #1\@empty \else \KV@split #1==\relax 
                                                  \expandafter \KV@do \fi 
<argument> a4paper,widh=100mm,
                              top=50mm
\setkeys ... {KV@#1@}\let \@tempc \relax \KV@do #2
                                                  ,\relax ,
\@ProcessOptionsKV ...keys {#2}{\@tempa }}\@tempa 
                                                  \AtEndOfPackage {\let \@un...
l.994 \ProcessOptionsKV[p]{Gm}
                              %
? 

This shows the macro expansion levels that lead to the error, by default LaTeX turns this off as it just exposes the implementation of the various commands that is not that interesting to most uses.

TeX has no record of where a particular macro was defined, only the definition that it has at the point of the error so it has no way of saying that the argument currently being processed by \ProcessOptionsKV was originally input from the line

\usepackage[a4paper,widh=100mm,top=50mm]{geometry}
David Carlisle
  • 757,742
  • TeX would not need any record. A common pattern with other languages is a backtrace. Say /macro1 -> calls /macro2, in which an error occurs, then not only would /macro2 cause an error message to be printed out, it would also hand back to /macro1 the information about the error occuring, which before continuing the execution would be able to add the information of the file and line number from which the failing /macro2 was called. – humanityANDpeace Aug 12 '16 at 22:27
  • the stack of macro execution is shown by \errorcontextlines but you want the stack of open file positions and as I comment above that is in the internals but not exposed. That would coincidentally give you the point where widh was entered, as \usepackage does \input. but \def\foo{ something \undefined} then 100 lines later use \foo you will get an error that \undefined is not defined, but tex has no record, even internally of where \foo was defined so it has no way of recording the line number or file where \undefined was entered. your widh example is not very different. – David Carlisle Aug 12 '16 at 22:33
  • @humanityANDpeace also note that it's a macro expansion language there are no function calls and no real stack, macros are expanded inline pushing their expansions into the input stream, control does not pop back up a stack at the end of the definition as it does in a compiled function call. – David Carlisle Aug 12 '16 at 22:38
  • very true. but that would not limit that the parsing of the source could not keep track of line numbers and execution sequence. Indeed as shown in the first update, after the error pdflatex continued in line 3 and could have therefore provided the information. I will have to look if there is a change to tweak (imho) improve pdflatex source. sorry for the lengthy comment. yet insightful for those with the problem of tracing error. – humanityANDpeace Aug 12 '16 at 22:47
3

Well, package geometry calls package keyval to validate the given options. The error message shows the line from the package that showed the error, package keyval. That is okay.

But you get the message that the invalid option widh was found.

Now you can search your code for the wrong spelled option.

If you have a greater look to the error message you will find:

("C:\Program Files\MiKTeX 2.9\tex\latex\geometry\geometry.cfg")

! Package keyval Error: widh undefined.

See the keyval package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.994 \ProcessOptionsKV[p]{Gm}
                              %
Try typing  <return>  to proceed.
If that doesn't work, type  X <return>  to quit.

Now you can see that package geometry causes the error message (first line in error message above).

Mensch
  • 65,388