Jelajahi Sumber

Improve bibliography import error handling (#4145)

GitOrigin-RevId: 3b379580635e1f6f2f518d416b8c72e0dadc0df6
Alf Eaton 5 tahun lalu
induk
melakukan
fe6970f30f

+ 4 - 0
services/web/app/src/Features/LinkedFiles/LinkedFilesController.js

@@ -176,6 +176,10 @@ module.exports = LinkedFilesController = {
       return res.status(400).send('This file cannot be refreshed')
     } else if (error.message === 'project_has_too_many_files') {
       return res.status(400).send('too many files')
+    } else if (/\bECONNREFUSED\b/.test(error.message)) {
+      return res
+        .status(500)
+        .send('Importing references is not currently available')
     } else {
       return next(error)
     }

+ 2 - 0
services/web/frontend/extracted-translations.json

@@ -178,6 +178,7 @@
   "math_display": "",
   "math_inline": "",
   "maximum_files_uploaded_together": "",
+  "mendeley_groups_loading_error": "",
   "mendeley_is_premium": "",
   "mendeley_reference_loading_error": "",
   "mendeley_reference_loading_error_expired": "",
@@ -325,6 +326,7 @@
   "work_with_non_overleaf_users": "",
   "your_message": "",
   "your_project_has_errors": "",
+  "zotero_groups_loading_error": "",
   "zotero_is_premium": "",
   "zotero_reference_loading_error": "",
   "zotero_reference_loading_error_expired": "",

+ 1 - 1
services/web/frontend/js/features/file-tree/components/file-tree-create/danger-message.js

@@ -6,5 +6,5 @@ export default function DangerMessage({ children }) {
   return <Alert bsStyle="danger">{children}</Alert>
 }
 DangerMessage.propTypes = {
-  children: PropTypes.string.isRequired,
+  children: PropTypes.any.isRequired,
 }

+ 6 - 7
services/web/frontend/stories/modals/create-file/create-file-modal-decorator.js

@@ -1,5 +1,4 @@
 import React, { useEffect } from 'react'
-import fetchMock from 'fetch-mock'
 import FileTreeContext from '../../../js/features/file-tree/components/file-tree-context'
 import FileTreeCreateNameProvider from '../../../js/features/file-tree/contexts/file-tree-create-name'
 import FileTreeCreateFormProvider from '../../../js/features/file-tree/contexts/file-tree-create-form'
@@ -37,13 +36,8 @@ const defaultContextProps = {
   },
 }
 
-export const createFileModalDecorator = (
-  contextProps = {},
-  createMode = 'doc'
-  // eslint-disable-next-line react/display-name
-) => Story => {
+export const mockCreateFileModalFetch = fetchMock =>
   fetchMock
-    .restore()
     .get('path:/user/projects', {
       projects: [
         {
@@ -104,6 +98,11 @@ export const createFileModalDecorator = (
       return 204
     })
 
+export const createFileModalDecorator = (
+  contextProps = {},
+  createMode = 'doc'
+  // eslint-disable-next-line react/display-name
+) => Story => {
   return (
     <FileTreeContext {...defaultContextProps} {...contextProps}>
       <FileTreeCreateNameProvider>

+ 74 - 6
services/web/frontend/stories/modals/create-file/create-file-modal.stories.js

@@ -1,18 +1,86 @@
-import React from 'react'
-import { createFileModalDecorator } from './create-file-modal-decorator'
+import React, { useEffect } from 'react'
+import {
+  createFileModalDecorator,
+  mockCreateFileModalFetch,
+} from './create-file-modal-decorator'
 import FileTreeModalCreateFile from '../../../js/features/file-tree/components/modals/file-tree-modal-create-file'
+import useFetchMock from '../../hooks/use-fetch-mock'
 
-export const MinimalFeatures = args => <FileTreeModalCreateFile {...args} />
+export const MinimalFeatures = args => {
+  useFetchMock(mockCreateFileModalFetch)
+
+  return <FileTreeModalCreateFile {...args} />
+}
 MinimalFeatures.decorators = [
   createFileModalDecorator({
     userHasFeature: () => false,
   }),
 ]
 
-export const WithExtraFeatures = args => <FileTreeModalCreateFile {...args} />
-WithExtraFeatures.decorators = [createFileModalDecorator()]
+export const WithExtraFeatures = args => {
+  useFetchMock(mockCreateFileModalFetch)
+
+  useEffect(() => {
+    const originalValue = window.ExposedSettings.hasLinkUrlFeature
+    window.ExposedSettings.hasLinkUrlFeature = true
+
+    return () => {
+      window.ExposedSettings.hasLinkUrlFeature = originalValue
+    }
+  }, [])
+
+  return <FileTreeModalCreateFile {...args} />
+}
+WithExtraFeatures.decorators = [
+  createFileModalDecorator({
+    refProviders: { mendeley: true, zotero: true },
+  }),
+]
+
+export const ErrorImportingFileFromExternalURL = args => {
+  useFetchMock(fetchMock => {
+    mockCreateFileModalFetch(fetchMock)
+
+    fetchMock.post('express:/project/:projectId/linked_file', 500, {
+      overwriteRoutes: true,
+    })
+  })
+
+  useEffect(() => {
+    const originalValue = window.ExposedSettings.hasLinkUrlFeature
+    window.ExposedSettings.hasLinkUrlFeature = true
+
+    return () => {
+      window.ExposedSettings.hasLinkUrlFeature = originalValue
+    }
+  }, [])
+
+  return <FileTreeModalCreateFile {...args} />
+}
+ErrorImportingFileFromExternalURL.decorators = [createFileModalDecorator()]
+
+export const ErrorImportingFileFromReferenceProvider = args => {
+  useFetchMock(fetchMock => {
+    mockCreateFileModalFetch(fetchMock)
+
+    fetchMock.post('express:/project/:projectId/linked_file', 500, {
+      overwriteRoutes: true,
+    })
+  })
+
+  return <FileTreeModalCreateFile {...args} />
+}
+ErrorImportingFileFromReferenceProvider.decorators = [
+  createFileModalDecorator({
+    refProviders: { mendeley: true, zotero: true },
+  }),
+]
+
+export const FileLimitReached = args => {
+  useFetchMock(mockCreateFileModalFetch)
 
-export const FileLimitReached = args => <FileTreeModalCreateFile {...args} />
+  return <FileTreeModalCreateFile {...args} />
+}
 FileLimitReached.decorators = [
   createFileModalDecorator({
     rootFolder: [

+ 2 - 0
services/web/locales/en.json

@@ -696,6 +696,7 @@
   "mendeley_reference_loading": "Loading references from Mendeley",
   "mendeley_reference_loading_success": "Loaded references from Mendeley",
   "mendeley_reference_loading_error": "Error, could not load references from Mendeley",
+  "mendeley_groups_loading_error": "There was an error loading groups from Mendeley",
   "zotero_integration": "Zotero Integration.",
   "zotero_sync_description": "With Zotero integration you can import your references from Zotero into your __appName__ projects.",
   "zotero_is_premium": "Zotero Integration is a premium feature",
@@ -704,6 +705,7 @@
   "zotero_reference_loading": "Loading references from Zotero",
   "zotero_reference_loading_success": "Loaded references from Zotero",
   "zotero_reference_loading_error": "Error, could not load references from Zotero",
+  "zotero_groups_loading_error": "There was an error loading groups from Zotero",
   "reference_import_button": "Import References to",
   "unlink_reference": "Unlink References Provider",
   "unlink_warning_reference": "Warning: When you unlink your account from this provider you will not be able to import references into your projects.",