6
\documentclass{article}
\usepackage{expl3}
\usepackage{everypage}

\ExplSyntaxOn
\AddEverypageHook { \sean_test: }

\msg_new:nnnn { test } { message }
  { this ~ is ~ a ~ rubbish ~ message }
  { it's ~ a ~ minimal ~ example }

\cs_new_protected:Npn \sean_test:
  {
    \typeout{++before++}
    \msg_fatal:nn { test } { message }
    \typeout{++after++}
  }

\ExplSyntaxOff

\usepackage{mwe}
\begin{document}
\lipsum[1-1000]
\end{document}

I'm rather surprised I was able to make a minimal example of this, but the above will produce (many copies of)

++after++
[26]
++before++

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Fatal test error: "message"
! 
! this is a rubbish message
! 
! See the test documentation for further information.
! 
! For immediate help type H <return>.
!...............................................  

l.23 \lipsum[1-1000]

! You can't use `\end' in internal vertical mode.
\__msg_fatal_code:nnnnnn ...l_text_tl }\tex_end:D 

l.23 \lipsum[1-1000]

++after++
[27]
++before++

What's with this business?

! You can't use `\end' in internal vertical mode.
\__msg_fatal_code:nnnnnn ...l_text_tl }\tex_end:D 

I tried introducing both \leavevmode\tex_end:D and \clearpage\tex_end:D to no effect.

Sean Allred
  • 27,421

2 Answers2

9

You can't die there.

The hook you are using is presumably run inside the output routine which is always internal vertical mode (as you are not, by definition, on the main vertical list) so you can not stop there, you need to exit the output routine first.


It's possible to do something to try dying outside the inner box, Die another day (quoted Paulo) but it isn't guaranteed that the aftergroup token lands somewhere safe (if it is ever safe to execute a fatal error)

\documentclass{article}
\usepackage{expl3}
\usepackage{everypage}

\ExplSyntaxOn

\AddEverypageHook { \sean_do_test: }
\cs_new:Nn \sean_do_test:
 {
  \bool_if:nTF { \mode_if_inner_p: || \mode_if_horizontal_p: }
   {
    \group_insert_after:N \sean_do_test:
   }
   {
    \sean_test:
   }
 }


\msg_new:nnnn { test } { message }
  { this ~ is ~ a ~ rubbish ~ message }
  { it's ~ a ~ minimal ~ example }

\cs_new_protected:Npn \sean_test:
  {
    \typeout{++before++}
    \msg_fatal:nn { test } { message }
    \typeout{++after++}
  }

\ExplSyntaxOff

\usepackage{mwe}
\begin{document}
\lipsum[1-1000]
\end{document}
egreg
  • 1,121,712
David Carlisle
  • 757,742
4

The fatal class of errors is really intended for major problems, almost certainly at load time. In your example you've ended up with it inside a box: TeX doesn't allow us to 'bail out' there, hence the error. We could perhaps add a guard to check the current mode and only try to \end if it's allowed, but essentially this is not the 'right' place to give a fatal error.

Joseph Wright
  • 259,911
  • 34
  • 706
  • 1,036