pdf-preview-error.js 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import PropTypes from 'prop-types'
  2. import { useTranslation, Trans } from 'react-i18next'
  3. import { memo, useCallback } from 'react'
  4. import { Button } from 'react-bootstrap'
  5. import PdfLogEntry from './pdf-log-entry'
  6. import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
  7. import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
  8. import getMeta from '../../../utils/meta'
  9. function PdfPreviewError({ error }) {
  10. const { t } = useTranslation()
  11. const { startCompile } = useCompileContext()
  12. switch (error) {
  13. case 'rendering-error-expected':
  14. return (
  15. <PdfLogEntry
  16. headerTitle={t('pdf_rendering_error')}
  17. formattedContent={
  18. <>
  19. <Trans i18nKey="something_went_wrong_rendering_pdf_expected">
  20. <Button
  21. bsSize="xs"
  22. bsStyle="info"
  23. onClick={() => startCompile()}
  24. />
  25. </Trans>
  26. <br />
  27. <br />
  28. <Trans
  29. i18nKey="last_resort_trouble_shooting_guide"
  30. components={[
  31. // eslint-disable-next-line jsx-a11y/anchor-has-content
  32. <a
  33. href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems"
  34. target="_blank"
  35. key="troubleshooting-link"
  36. />,
  37. ]}
  38. />
  39. </>
  40. }
  41. level="warning"
  42. />
  43. )
  44. case 'rendering-error':
  45. return (
  46. <ErrorLogEntry title={t('pdf_rendering_error')}>
  47. {t('something_went_wrong_rendering_pdf')}
  48. &nbsp;
  49. <Trans
  50. i18nKey="try_recompile_project_or_troubleshoot"
  51. components={[
  52. // eslint-disable-next-line jsx-a11y/anchor-has-content
  53. <a
  54. href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems"
  55. target="_blank"
  56. key="troubleshooting-link"
  57. />,
  58. ]}
  59. />
  60. {getMeta('ol-compilesUserContentDomain') && (
  61. <>
  62. <br />
  63. <br />
  64. <Trans
  65. i18nKey="new_compile_domain_notice"
  66. values={{
  67. compilesUserContentDomain: new URL(
  68. getMeta('ol-compilesUserContentDomain')
  69. ).hostname,
  70. }}
  71. components={[
  72. <code key="domain" />,
  73. /* eslint-disable-next-line jsx-a11y/anchor-has-content */
  74. <a
  75. href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems"
  76. target="_blank"
  77. key="troubleshooting-link"
  78. />,
  79. ]}
  80. />
  81. </>
  82. )}
  83. </ErrorLogEntry>
  84. )
  85. case 'clsi-maintenance':
  86. return (
  87. <ErrorLogEntry title={t('server_error')}>
  88. {t('clsi_maintenance')}
  89. </ErrorLogEntry>
  90. )
  91. case 'clsi-unavailable':
  92. return (
  93. <ErrorLogEntry title={t('server_error')}>
  94. {t('clsi_unavailable')}
  95. </ErrorLogEntry>
  96. )
  97. case 'too-recently-compiled':
  98. return (
  99. <ErrorLogEntry title={t('server_error')}>
  100. {t('too_recently_compiled')}
  101. </ErrorLogEntry>
  102. )
  103. case 'terminated':
  104. return (
  105. <ErrorLogEntry title={t('terminated')}>
  106. {t('compile_terminated_by_user')}
  107. </ErrorLogEntry>
  108. )
  109. case 'rate-limited':
  110. return (
  111. <ErrorLogEntry title={t('pdf_compile_rate_limit_hit')}>
  112. {t('project_flagged_too_many_compiles')}
  113. </ErrorLogEntry>
  114. )
  115. case 'compile-in-progress':
  116. return (
  117. <ErrorLogEntry title={t('pdf_compile_in_progress_error')}>
  118. {t('pdf_compile_try_again')}
  119. </ErrorLogEntry>
  120. )
  121. case 'auto-compile-disabled':
  122. return (
  123. <ErrorLogEntry title={t('autocompile_disabled')}>
  124. {t('autocompile_disabled_reason')}
  125. </ErrorLogEntry>
  126. )
  127. case 'project-too-large':
  128. return (
  129. <ErrorLogEntry title={t('project_too_large')}>
  130. {t('project_too_much_editable_text')}
  131. </ErrorLogEntry>
  132. )
  133. case 'timedout':
  134. return <TimedOutLogEntry />
  135. case 'failure':
  136. return (
  137. <ErrorLogEntry title={t('no_pdf_error_title')}>
  138. {t('no_pdf_error_explanation')}
  139. <ul className="log-entry-formatted-content-list">
  140. <li>{t('no_pdf_error_reason_unrecoverable_error')}</li>
  141. <li>
  142. <Trans
  143. i18nKey="no_pdf_error_reason_no_content"
  144. components={{ code: <code /> }}
  145. />
  146. </li>
  147. <li>
  148. <Trans
  149. i18nKey="no_pdf_error_reason_output_pdf_already_exists"
  150. components={{ code: <code /> }}
  151. />
  152. </li>
  153. </ul>
  154. </ErrorLogEntry>
  155. )
  156. case 'clear-cache':
  157. return (
  158. <ErrorLogEntry title={t('server_error')}>
  159. {t('somthing_went_wrong_compiling')}
  160. </ErrorLogEntry>
  161. )
  162. case 'pdf-viewer-loading-error':
  163. return (
  164. <ErrorLogEntry title={t('pdf_rendering_error')}>
  165. <Trans
  166. i18nKey="something_went_wrong_loading_pdf_viewer"
  167. components={[
  168. <strong key="strong-" />,
  169. // eslint-disable-next-line jsx-a11y/anchor-has-content
  170. <a
  171. href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems"
  172. target="_blank"
  173. key="troubleshooting-link"
  174. />,
  175. // eslint-disable-next-line jsx-a11y/anchor-has-content
  176. <a key="contact-link" target="_blank" href="/contact" />,
  177. ]}
  178. />
  179. </ErrorLogEntry>
  180. )
  181. case 'validation-problems':
  182. return null // handled elsewhere
  183. case 'error':
  184. default:
  185. return (
  186. <ErrorLogEntry title={t('server_error')}>
  187. {t('somthing_went_wrong_compiling')}
  188. </ErrorLogEntry>
  189. )
  190. }
  191. }
  192. PdfPreviewError.propTypes = {
  193. error: PropTypes.string.isRequired,
  194. }
  195. export default memo(PdfPreviewError)
  196. function ErrorLogEntry({ title, headerIcon, children }) {
  197. const { t } = useTranslation()
  198. return (
  199. <PdfLogEntry
  200. headerTitle={title}
  201. headerIcon={headerIcon}
  202. formattedContent={children}
  203. entryAriaLabel={t('compile_error_entry_description')}
  204. level="error"
  205. />
  206. )
  207. }
  208. ErrorLogEntry.propTypes = {
  209. title: PropTypes.string.isRequired,
  210. headerIcon: PropTypes.element,
  211. children: PropTypes.any.isRequired,
  212. }
  213. function TimedOutLogEntry() {
  214. const { t } = useTranslation()
  215. const { enableStopOnFirstError } = useStopOnFirstError({
  216. eventSource: 'timeout',
  217. })
  218. const { startCompile, lastCompileOptions, setAnimateCompileDropdownArrow } =
  219. useCompileContext()
  220. const handleEnableStopOnFirstErrorClick = useCallback(() => {
  221. enableStopOnFirstError()
  222. startCompile({ stopOnFirstError: true })
  223. setAnimateCompileDropdownArrow(true)
  224. }, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
  225. return (
  226. <ErrorLogEntry title={t('timedout')}>
  227. <p>{t('project_timed_out_intro')}</p>
  228. <ul>
  229. <li>
  230. <Trans
  231. i18nKey="project_timed_out_optimize_images"
  232. components={[
  233. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  234. <a href="https://www.overleaf.com/learn/how-to/Optimising_very_large_image_files" />,
  235. ]}
  236. />
  237. </li>
  238. <li>
  239. <Trans
  240. i18nKey="project_timed_out_fatal_error"
  241. components={[
  242. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  243. <a href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F#Fatal_compile_errors_blocking_the_compilation" />,
  244. ]}
  245. />
  246. {!lastCompileOptions.stopOnFirstError && (
  247. <>
  248. {' '}
  249. <Trans
  250. i18nKey="project_timed_out_enable_stop_on_first_error"
  251. components={[
  252. // eslint-disable-next-line react/jsx-key
  253. <Button
  254. bsSize="xs"
  255. bsStyle="info"
  256. onClick={handleEnableStopOnFirstErrorClick}
  257. />,
  258. ]}
  259. />{' '}
  260. </>
  261. )}
  262. </li>
  263. </ul>
  264. <p>
  265. <Trans
  266. i18nKey="project_timed_out_learn_more"
  267. components={[
  268. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  269. <a href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F" />,
  270. ]}
  271. />
  272. </p>
  273. </ErrorLogEntry>
  274. )
  275. }
  276. TimedOutLogEntry.propTypes = {}