pdf-preview-error.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  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 StopOnFirstErrorBadge from '../../../shared/components/stop-on-first-error-badge'
  9. function PdfPreviewError({ error }) {
  10. const { t } = useTranslation()
  11. switch (error) {
  12. case 'rendering-error':
  13. return (
  14. <ErrorLogEntry title={t('pdf_rendering_error')}>
  15. {t('something_went_wrong_rendering_pdf')}
  16. &nbsp;
  17. <Trans
  18. i18nKey="try_recompile_project_or_troubleshoot"
  19. components={[
  20. // eslint-disable-next-line react/jsx-key, jsx-a11y/anchor-has-content
  21. <a href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems" />,
  22. ]}
  23. />
  24. </ErrorLogEntry>
  25. )
  26. case 'clsi-maintenance':
  27. return (
  28. <ErrorLogEntry title={t('server_error')}>
  29. {t('clsi_maintenance')}
  30. </ErrorLogEntry>
  31. )
  32. case 'clsi-unavailable':
  33. return (
  34. <ErrorLogEntry title={t('server_error')}>
  35. {t('clsi_unavailable')}
  36. </ErrorLogEntry>
  37. )
  38. case 'too-recently-compiled':
  39. return (
  40. <ErrorLogEntry title={t('server_error')}>
  41. {t('too_recently_compiled')}
  42. </ErrorLogEntry>
  43. )
  44. case 'terminated':
  45. return (
  46. <ErrorLogEntry title={t('terminated')}>
  47. {t('compile_terminated_by_user')}
  48. </ErrorLogEntry>
  49. )
  50. case 'rate-limited':
  51. return (
  52. <ErrorLogEntry title={t('pdf_compile_rate_limit_hit')}>
  53. {t('project_flagged_too_many_compiles')}
  54. </ErrorLogEntry>
  55. )
  56. case 'compile-in-progress':
  57. return (
  58. <ErrorLogEntry title={t('pdf_compile_in_progress_error')}>
  59. {t('pdf_compile_try_again')}
  60. </ErrorLogEntry>
  61. )
  62. case 'auto-compile-disabled':
  63. return (
  64. <ErrorLogEntry title={t('autocompile_disabled')}>
  65. {t('autocompile_disabled_reason')}
  66. </ErrorLogEntry>
  67. )
  68. case 'project-too-large':
  69. return (
  70. <ErrorLogEntry title={t('project_too_large')}>
  71. {t('project_too_much_editable_text')}
  72. </ErrorLogEntry>
  73. )
  74. case 'timedout':
  75. return <TimedOutLogEntry />
  76. case 'failure':
  77. return (
  78. <ErrorLogEntry title={t('no_pdf_error_title')}>
  79. {t('no_pdf_error_explanation')}
  80. <ul className="log-entry-formatted-content-list">
  81. <li>{t('no_pdf_error_reason_unrecoverable_error')}</li>
  82. <li>
  83. <Trans
  84. i18nKey="no_pdf_error_reason_no_content"
  85. components={{ code: <code /> }}
  86. />
  87. </li>
  88. <li>
  89. <Trans
  90. i18nKey="no_pdf_error_reason_output_pdf_already_exists"
  91. components={{ code: <code /> }}
  92. />
  93. </li>
  94. </ul>
  95. </ErrorLogEntry>
  96. )
  97. case 'clear-cache':
  98. return (
  99. <ErrorLogEntry title={t('server_error')}>
  100. {t('somthing_went_wrong_compiling')}
  101. </ErrorLogEntry>
  102. )
  103. case 'pdf-viewer-loading-error':
  104. return (
  105. <ErrorLogEntry title={t('pdf_rendering_error')}>
  106. <Trans
  107. i18nKey="something_went_wrong_loading_pdf_viewer"
  108. components={[
  109. <strong key="strong-" />,
  110. // eslint-disable-next-line jsx-a11y/anchor-has-content
  111. <a
  112. key="learn-link"
  113. target="_blank"
  114. href="/learn/how-to/Resolving_access%2C_loading%2C_and_display_problems"
  115. />,
  116. // eslint-disable-next-line jsx-a11y/anchor-has-content
  117. <a key="contact-link" target="_blank" href="/contact" />,
  118. ]}
  119. />
  120. </ErrorLogEntry>
  121. )
  122. case 'validation-problems':
  123. return null // handled elsewhere
  124. case 'error':
  125. default:
  126. return (
  127. <ErrorLogEntry title={t('server_error')}>
  128. {t('somthing_went_wrong_compiling')}
  129. </ErrorLogEntry>
  130. )
  131. }
  132. }
  133. PdfPreviewError.propTypes = {
  134. error: PropTypes.string.isRequired,
  135. }
  136. export default memo(PdfPreviewError)
  137. function ErrorLogEntry({ title, headerIcon, children }) {
  138. const { t } = useTranslation()
  139. return (
  140. <PdfLogEntry
  141. headerTitle={title}
  142. headerIcon={headerIcon}
  143. formattedContent={children}
  144. entryAriaLabel={t('compile_error_entry_description')}
  145. level="error"
  146. />
  147. )
  148. }
  149. ErrorLogEntry.propTypes = {
  150. title: PropTypes.string.isRequired,
  151. headerIcon: PropTypes.element,
  152. children: PropTypes.any.isRequired,
  153. }
  154. function TimedOutLogEntry() {
  155. const { t } = useTranslation()
  156. const { enableStopOnFirstError } = useStopOnFirstError({
  157. eventSource: 'timeout',
  158. })
  159. const { startCompile, lastCompileOptions, setAnimateCompileDropdownArrow } =
  160. useCompileContext()
  161. const handleEnableStopOnFirstErrorClick = useCallback(() => {
  162. enableStopOnFirstError()
  163. startCompile({ stopOnFirstError: true })
  164. setAnimateCompileDropdownArrow(true)
  165. }, [enableStopOnFirstError, startCompile, setAnimateCompileDropdownArrow])
  166. return (
  167. <ErrorLogEntry title={t('timedout')}>
  168. <p>{t('project_timed_out_intro')}</p>
  169. <ul>
  170. <li>
  171. <Trans
  172. i18nKey="project_timed_out_optimize_images"
  173. components={[
  174. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  175. <a href="https://www.overleaf.com/learn/how-to/Optimising_very_large_image_files" />,
  176. ]}
  177. />
  178. </li>
  179. <li>
  180. <Trans
  181. i18nKey="project_timed_out_fatal_error"
  182. components={[
  183. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  184. <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" />,
  185. ]}
  186. />
  187. {!lastCompileOptions.stopOnFirstError && (
  188. <>
  189. {' '}
  190. <Trans
  191. i18nKey="project_timed_out_enable_stop_on_first_error"
  192. components={[
  193. // eslint-disable-next-line react/jsx-key
  194. <Button
  195. bsSize="xs"
  196. bsStyle="info"
  197. onClick={handleEnableStopOnFirstErrorClick}
  198. />,
  199. ]}
  200. />{' '}
  201. <StopOnFirstErrorBadge placement="bottom" />
  202. </>
  203. )}
  204. </li>
  205. </ul>
  206. <p>
  207. <Trans
  208. i18nKey="project_timed_out_learn_more"
  209. components={[
  210. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  211. <a href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F" />,
  212. ]}
  213. />
  214. </p>
  215. </ErrorLogEntry>
  216. )
  217. }
  218. TimedOutLogEntry.propTypes = {}