Почему \msg_fatal: показывает, казалось бы, не связанную ошибку?

Почему \msg_fatal: показывает, казалось бы, не связанную ошибку?
\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}

Я довольно удивлен, что мне удалось сделать минимальный пример этого, но вышеприведенный код даст (множество копий)

++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++

Что с этим бизнесом?

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

Я пробовал ввести оба варианта \leavevmode\tex_end:D, но \clearpage\tex_end:Dбезрезультатно.

решение1

Там нельзя умереть.

Хук, который вы используете, предположительно, запускается внутри процедуры вывода, которая всегда находится во внутреннем вертикальном режиме (поскольку вы по определению не находитесь в главном вертикальном списке), поэтому вы не можете остановиться на этом, вам сначала нужно выйти из процедуры вывода.


Можно что-то сделать, чтобы попытаться умереть вне внутренней коробки,Умереть в другой день(цитата Пауло) но нет гарантии, что токен aftergroup попадет в безопасное место (если вообще возможно безопасно выполнить фатальную ошибку)

\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}

решение2

Класс fatalошибок на самом деле предназначен для серьезных проблем, почти наверняка во время загрузки. В вашем примере вы оказались внутри коробки: TeX не позволяет нам «выйти» оттуда, отсюда и ошибка. Мы могли бы, возможно, добавить охрану для проверки текущего режима и пытаться делать это только в том \endслучае, если это разрешено, но по сути это не «правильное» место для сообщения о фатальной ошибке.

Связанный контент