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:
Eric Mc Sween 2022-06-09 10:47:53 -04:00 committed by Copybot
parent 767a671a38
commit e365a6cbaf
7 changed files with 170 additions and 28 deletions

View file

@ -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": "",

View file

@ -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} />}

View file

@ -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 (

View file

@ -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 ? (
&nbsp; 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 &nbsp;
/> <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" />
&nbsp;
<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" />]} &nbsp;
/> {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>

View file

@ -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,

View file

@ -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,

View file

@ -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 couldnt compile for some reason. Please check the errors below for details, or view the raw log", "generic_failed_compile_message": "Sorry, your LaTeX code couldnt compile for some reason. Please check the errors below for details, or view the raw log",