mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #8346 from overleaf/em-halt-on-error-logs-2
Stop on first error: logs pane prompts GitOrigin-RevId: a246a7e5d302ad3104e15f7fd78344992b4e011b
This commit is contained in:
parent
767a671a38
commit
e365a6cbaf
7 changed files with 170 additions and 28 deletions
|
@ -246,8 +246,10 @@
|
||||||
"loading_recent_github_commits": "",
|
"loading_recent_github_commits": "",
|
||||||
"log_entry_description": "",
|
"log_entry_description": "",
|
||||||
"log_entry_maximum_entries": "",
|
"log_entry_maximum_entries": "",
|
||||||
|
"log_entry_maximum_entries_enable_stop_on_first_error": "",
|
||||||
"log_entry_maximum_entries_message": "",
|
"log_entry_maximum_entries_message": "",
|
||||||
"log_entry_maximum_entries_message_no_errors": "",
|
"log_entry_maximum_entries_message_no_errors": "",
|
||||||
|
"log_entry_maximum_entries_see_full_logs": "",
|
||||||
"log_entry_maximum_entries_title": "",
|
"log_entry_maximum_entries_title": "",
|
||||||
"log_hint_extra_info": "",
|
"log_hint_extra_info": "",
|
||||||
"log_viewer_error": "",
|
"log_viewer_error": "",
|
||||||
|
@ -351,6 +353,11 @@
|
||||||
"project_ownership_transfer_confirmation_2": "",
|
"project_ownership_transfer_confirmation_2": "",
|
||||||
"project_synced_with_git_repo_at": "",
|
"project_synced_with_git_repo_at": "",
|
||||||
"project_synchronisation": "",
|
"project_synchronisation": "",
|
||||||
|
"project_timed_out_enable_stop_on_first_error": "",
|
||||||
|
"project_timed_out_fatal_error": "",
|
||||||
|
"project_timed_out_intro": "",
|
||||||
|
"project_timed_out_learn_more": "",
|
||||||
|
"project_timed_out_optimize_images": "",
|
||||||
"project_too_large": "",
|
"project_too_large": "",
|
||||||
"project_too_large_please_reduce": "",
|
"project_too_large_please_reduce": "",
|
||||||
"project_too_much_editable_text": "",
|
"project_too_much_editable_text": "",
|
||||||
|
@ -459,6 +466,7 @@
|
||||||
"this_project_is_public_read_only": "",
|
"this_project_is_public_read_only": "",
|
||||||
"this_project_will_appear_in_your_dropbox_folder_at": "",
|
"this_project_will_appear_in_your_dropbox_folder_at": "",
|
||||||
"timedout": "",
|
"timedout": "",
|
||||||
|
"tip": "",
|
||||||
"to_add_email_accounts_need_to_be_linked_2": "",
|
"to_add_email_accounts_need_to_be_linked_2": "",
|
||||||
"to_add_more_collaborators": "",
|
"to_add_more_collaborators": "",
|
||||||
"to_change_access_permissions": "",
|
"to_change_access_permissions": "",
|
||||||
|
|
|
@ -22,7 +22,6 @@ function PdfLogsViewer() {
|
||||||
rawLog,
|
rawLog,
|
||||||
validationIssues,
|
validationIssues,
|
||||||
showLogs,
|
showLogs,
|
||||||
stopOnFirstError,
|
|
||||||
stoppedOnFirstError,
|
stoppedOnFirstError,
|
||||||
} = useCompileContext()
|
} = useCompileContext()
|
||||||
|
|
||||||
|
@ -33,7 +32,7 @@ function PdfLogsViewer() {
|
||||||
<div className="logs-pane-content">
|
<div className="logs-pane-content">
|
||||||
{codeCheckFailed && <PdfCodeCheckFailedNotice />}
|
{codeCheckFailed && <PdfCodeCheckFailedNotice />}
|
||||||
|
|
||||||
{stopOnFirstError && stoppedOnFirstError && <StopOnFirstErrorPrompt />}
|
{stoppedOnFirstError && <StopOnFirstErrorPrompt />}
|
||||||
|
|
||||||
{error && <PdfPreviewError error={error} />}
|
{error && <PdfPreviewError error={error} />}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { useTranslation, Trans } from 'react-i18next'
|
import { useTranslation, Trans } from 'react-i18next'
|
||||||
import { memo } from 'react'
|
import { memo } from 'react'
|
||||||
|
import { Button } from 'react-bootstrap'
|
||||||
import PdfLogEntry from './pdf-log-entry'
|
import PdfLogEntry from './pdf-log-entry'
|
||||||
|
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||||
|
import getMeta from '../../../utils/meta'
|
||||||
|
|
||||||
function PdfPreviewError({ error }) {
|
function PdfPreviewError({ error }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const { lastCompileOptions, setStopOnFirstError, startCompile } =
|
||||||
|
useCompileContext()
|
||||||
|
|
||||||
switch (error) {
|
switch (error) {
|
||||||
case 'rendering-error':
|
case 'rendering-error':
|
||||||
|
@ -70,22 +75,82 @@ function PdfPreviewError({ error }) {
|
||||||
</ErrorLogEntry>
|
</ErrorLogEntry>
|
||||||
)
|
)
|
||||||
|
|
||||||
case 'timedout':
|
case 'timedout': {
|
||||||
return (
|
const showStopOnFirstError = getMeta('ol-showStopOnFirstError')
|
||||||
<ErrorLogEntry title={t('timedout')}>
|
if (showStopOnFirstError) {
|
||||||
{t('proj_timed_out_reason')}
|
return (
|
||||||
|
<ErrorLogEntry title={t('timedout')}>
|
||||||
|
<p>{t('project_timed_out_intro')}</p>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<Trans
|
||||||
|
i18nKey="project_timed_out_optimize_images"
|
||||||
|
components={[
|
||||||
|
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
|
||||||
|
<a href="https://www.overleaf.com/learn/how-to/Optimising_very_large_image_files" />,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Trans
|
||||||
|
i18nKey="project_timed_out_fatal_error"
|
||||||
|
components={[
|
||||||
|
// eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
|
||||||
|
<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" />,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
{!lastCompileOptions.stopOnFirstError && (
|
||||||
|
<>
|
||||||
|
{' '}
|
||||||
|
<Trans
|
||||||
|
i18nKey="project_timed_out_enable_stop_on_first_error"
|
||||||
|
components={[
|
||||||
|
// eslint-disable-next-line react/jsx-key
|
||||||
|
<Button
|
||||||
|
bsSize="xs"
|
||||||
|
bsStyle="info"
|
||||||
|
onClick={() => {
|
||||||
|
startCompile({ stopOnFirstError: true })
|
||||||
|
setStopOnFirstError(true)
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>
|
||||||
|
<Trans
|
||||||
|
i18nKey="project_timed_out_learn_more"
|
||||||
|
components={{
|
||||||
|
link: (
|
||||||
|
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||||
|
<a href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F" />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
</ErrorLogEntry>
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<ErrorLogEntry title={t('timedout')}>
|
||||||
|
{t('proj_timed_out_reason')}
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a
|
<a
|
||||||
href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F"
|
href="https://www.overleaf.com/learn/how-to/Why_do_I_keep_getting_the_compile_timeout_error_message%3F"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
>
|
>
|
||||||
{t('learn_how_to_make_documents_compile_quickly')}
|
{t('learn_how_to_make_documents_compile_quickly')}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</ErrorLogEntry>
|
</ErrorLogEntry>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
case 'failure':
|
case 'failure':
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import { Trans, useTranslation } from 'react-i18next'
|
import { Trans, useTranslation } from 'react-i18next'
|
||||||
|
import { Button } from 'react-bootstrap'
|
||||||
import PreviewLogEntryHeader from './preview-log-entry-header'
|
import PreviewLogEntryHeader from './preview-log-entry-header'
|
||||||
import Icon from '../../../shared/components/icon'
|
import Icon from '../../../shared/components/icon'
|
||||||
|
import getMeta from '../../../utils/meta'
|
||||||
|
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||||
|
|
||||||
function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
|
function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
const showStopOnFirstError = getMeta('ol-showStopOnFirstError')
|
||||||
|
const { startCompile, setStopOnFirstError, stoppedOnFirstError } =
|
||||||
|
useCompileContext()
|
||||||
|
|
||||||
const title = t('log_entry_maximum_entries_title', {
|
const title = t('log_entry_maximum_entries_title', {
|
||||||
total: totalEntries,
|
total: totalEntries,
|
||||||
|
@ -15,18 +21,59 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
|
||||||
<div className="log-entry" aria-label={t('log_entry_maximum_entries')}>
|
<div className="log-entry" aria-label={t('log_entry_maximum_entries')}>
|
||||||
<PreviewLogEntryHeader level="raw" headerTitle={title} />
|
<PreviewLogEntryHeader level="raw" headerTitle={title} />
|
||||||
<div className="log-entry-content">
|
<div className="log-entry-content">
|
||||||
<Icon type="lightbulb-o" />
|
{showStopOnFirstError ? (
|
||||||
|
hasErrors && !stoppedOnFirstError ? (
|
||||||
{hasErrors ? (
|
<>
|
||||||
<Trans
|
<p>
|
||||||
i18nKey="log_entry_maximum_entries_message"
|
<Icon type="lightbulb-o" />
|
||||||
components={[<b key="bold-1" />, <p />]} // eslint-disable-line react/jsx-key
|
|
||||||
/>
|
<strong>{t('tip')}: </strong>
|
||||||
|
<Trans
|
||||||
|
i18nKey="log_entry_maximum_entries_enable_stop_on_first_error"
|
||||||
|
components={{
|
||||||
|
button: (
|
||||||
|
<Button
|
||||||
|
bsSize="xs"
|
||||||
|
bsStyle="info"
|
||||||
|
onClick={() => {
|
||||||
|
startCompile({ stopOnFirstError: true })
|
||||||
|
setStopOnFirstError(true)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
'learn-more-link': (
|
||||||
|
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
||||||
|
<a href="https://www.overleaf.com/learn/latex/Questions/Tips_and_Tricks_for_Troubleshooting_LaTeX" />
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</p>
|
||||||
|
<p>{t('log_entry_maximum_entries_see_full_logs')}</p>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<p>
|
||||||
|
<Icon type="lightbulb-o" />
|
||||||
|
|
||||||
|
<strong>{t('tip')}: </strong>
|
||||||
|
{t('log_entry_maximum_entries_see_full_logs')}
|
||||||
|
</p>
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
<Trans
|
<>
|
||||||
i18nKey="log_entry_maximum_entries_message_no_errors"
|
<Icon type="lightbulb-o" />
|
||||||
components={[<b key="bold-1" />]}
|
|
||||||
/>
|
{hasErrors ? (
|
||||||
|
<Trans
|
||||||
|
i18nKey="log_entry_maximum_entries_message"
|
||||||
|
components={[<b />, <p />]} // eslint-disable-line react/jsx-key
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Trans
|
||||||
|
i18nKey="log_entry_maximum_entries_message_no_errors"
|
||||||
|
components={[<b />]} // eslint-disable-line react/jsx-key
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -30,6 +30,7 @@ export function DetachCompileProvider({ children }) {
|
||||||
fileList: _fileList,
|
fileList: _fileList,
|
||||||
hasChanges: _hasChanges,
|
hasChanges: _hasChanges,
|
||||||
highlights: _highlights,
|
highlights: _highlights,
|
||||||
|
lastCompileOptions: _lastCompileOptions,
|
||||||
logEntries: _logEntries,
|
logEntries: _logEntries,
|
||||||
logEntryAnnotations: _logEntryAnnotations,
|
logEntryAnnotations: _logEntryAnnotations,
|
||||||
pdfDownloadUrl: _pdfDownloadUrl,
|
pdfDownloadUrl: _pdfDownloadUrl,
|
||||||
|
@ -113,6 +114,12 @@ export function DetachCompileProvider({ children }) {
|
||||||
'detacher',
|
'detacher',
|
||||||
'detached'
|
'detached'
|
||||||
)
|
)
|
||||||
|
const [lastCompileOptions] = useDetachStateWatcher(
|
||||||
|
'lastCompileOptions',
|
||||||
|
_lastCompileOptions,
|
||||||
|
'detacher',
|
||||||
|
'detached'
|
||||||
|
)
|
||||||
const [logEntries] = useDetachStateWatcher(
|
const [logEntries] = useDetachStateWatcher(
|
||||||
'logEntries',
|
'logEntries',
|
||||||
_logEntries,
|
_logEntries,
|
||||||
|
@ -314,6 +321,7 @@ export function DetachCompileProvider({ children }) {
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
highlights,
|
highlights,
|
||||||
|
lastCompileOptions,
|
||||||
logEntryAnnotations,
|
logEntryAnnotations,
|
||||||
logEntries,
|
logEntries,
|
||||||
pdfDownloadUrl,
|
pdfDownloadUrl,
|
||||||
|
@ -357,6 +365,7 @@ export function DetachCompileProvider({ children }) {
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
highlights,
|
highlights,
|
||||||
|
lastCompileOptions,
|
||||||
logEntryAnnotations,
|
logEntryAnnotations,
|
||||||
logEntries,
|
logEntries,
|
||||||
pdfDownloadUrl,
|
pdfDownloadUrl,
|
||||||
|
|
|
@ -458,6 +458,10 @@ export function LocalCompileProvider({ children }) {
|
||||||
})
|
})
|
||||||
}, [clearCache, compiler])
|
}, [clearCache, compiler])
|
||||||
|
|
||||||
|
// After a compile, the compiler sets `data.options` to the options that were
|
||||||
|
// used for that compile.
|
||||||
|
const lastCompileOptions = useMemo(() => data?.options || {}, [data])
|
||||||
|
|
||||||
const value = useMemo(
|
const value = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
autoCompile,
|
autoCompile,
|
||||||
|
@ -471,6 +475,7 @@ export function LocalCompileProvider({ children }) {
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
highlights,
|
highlights,
|
||||||
|
lastCompileOptions,
|
||||||
logEntryAnnotations,
|
logEntryAnnotations,
|
||||||
logEntries,
|
logEntries,
|
||||||
pdfDownloadUrl,
|
pdfDownloadUrl,
|
||||||
|
@ -514,6 +519,7 @@ export function LocalCompileProvider({ children }) {
|
||||||
fileList,
|
fileList,
|
||||||
hasChanges,
|
hasChanges,
|
||||||
highlights,
|
highlights,
|
||||||
|
lastCompileOptions,
|
||||||
logEntries,
|
logEntries,
|
||||||
logEntryAnnotations,
|
logEntryAnnotations,
|
||||||
position,
|
position,
|
||||||
|
|
|
@ -34,6 +34,9 @@
|
||||||
"log_entry_maximum_entries_title": "__total__ log messages total. Showing the first __displayed__",
|
"log_entry_maximum_entries_title": "__total__ log messages total. Showing the first __displayed__",
|
||||||
"log_entry_maximum_entries_message": "<0>Tip</0>: Try to fix the first error and recompile. Often one error causes many later error messages.<1>If you need to see the full logs, you can still download them or view the raw logs below.</1>",
|
"log_entry_maximum_entries_message": "<0>Tip</0>: Try to fix the first error and recompile. Often one error causes many later error messages.<1>If you need to see the full logs, you can still download them or view the raw logs below.</1>",
|
||||||
"log_entry_maximum_entries_message_no_errors": "<0>Tip</0>: If you need to see the full logs, you can still download them or view the raw logs below.",
|
"log_entry_maximum_entries_message_no_errors": "<0>Tip</0>: If you need to see the full logs, you can still download them or view the raw logs below.",
|
||||||
|
"log_entry_maximum_entries_enable_stop_on_first_error": "Try to fix the first error and recompile. Often one error causes many later error messages. You can <button>Enable “Stop on first error”</button> to focus on fixing errors. We recommend fixing errors as soon as possible; letting them accumulate may lead to hard-to-debug and fatal errors. <learn-more-link>Learn more</learn-more-link>",
|
||||||
|
"log_entry_maximum_entries_see_full_logs": "If you need to see the full logs, you can still download them or view the raw logs below.",
|
||||||
|
"tip": "Tip",
|
||||||
"navigate_log_source": "Navigate to log position in source code: __location__",
|
"navigate_log_source": "Navigate to log position in source code: __location__",
|
||||||
"other_output_files": "Download other output files",
|
"other_output_files": "Download other output files",
|
||||||
"refresh": "Refresh",
|
"refresh": "Refresh",
|
||||||
|
@ -1082,6 +1085,11 @@
|
||||||
"something_went_wrong_loading_pdf_viewer": "Something went wrong loading the PDF viewer. This might be caused by issues like <0>temporary network problems</0> or an <0>outdated web browser</0>. Please follow the <1>troubleshooting steps for access, loading and display problems</1>. If the issue persists, please <2>let us know</2>.",
|
"something_went_wrong_loading_pdf_viewer": "Something went wrong loading the PDF viewer. This might be caused by issues like <0>temporary network problems</0> or an <0>outdated web browser</0>. Please follow the <1>troubleshooting steps for access, loading and display problems</1>. If the issue persists, please <2>let us know</2>.",
|
||||||
"timedout": "Timed out",
|
"timedout": "Timed out",
|
||||||
"proj_timed_out_reason": "Sorry, your compile took too long to run and timed out. This may be due to a LaTeX error, or a large number of high-res images or complicated diagrams.",
|
"proj_timed_out_reason": "Sorry, your compile took too long to run and timed out. This may be due to a LaTeX error, or a large number of high-res images or complicated diagrams.",
|
||||||
|
"project_timed_out_intro": "Sorry, your compile took too long to run and timed out. The most common causes of timeouts are:",
|
||||||
|
"project_timed_out_optimize_images": "Large or high-resolution images are taking too long to process. You may be able to <0>optimize them</0>.",
|
||||||
|
"project_timed_out_fatal_error": "A <0>fatal compile error</0> may be completely blocking compilation.",
|
||||||
|
"project_timed_out_enable_stop_on_first_error": "<0>Enable “Stop on first error”</0> to help you find and fix errors right away.",
|
||||||
|
"project_timed_out_learn_more": "<0>Learn more</0> about other causes of compile timeouts and how to fix them.",
|
||||||
"no_errors_good_job": "No errors, good job!",
|
"no_errors_good_job": "No errors, good job!",
|
||||||
"compile_error": "Compile Error",
|
"compile_error": "Compile Error",
|
||||||
"generic_failed_compile_message": "Sorry, your LaTeX code couldn’t compile for some reason. Please check the errors below for details, or view the raw log",
|
"generic_failed_compile_message": "Sorry, your LaTeX code couldn’t compile for some reason. Please check the errors below for details, or view the raw log",
|
||||||
|
|
Loading…
Reference in a new issue