error-message.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import { useTranslation, Trans } from 'react-i18next'
  2. import { FetchError } from '../../../../infrastructure/fetch-json'
  3. import RedirectToLogin from './redirect-to-login'
  4. import {
  5. BlockedFilenameError,
  6. DuplicateFilenameError,
  7. InvalidFilenameError,
  8. } from '../../errors'
  9. import DangerMessage from './danger-message'
  10. import getMeta from '@/utils/meta'
  11. // TODO: Update the error type when we properly type FileTreeActionableContext
  12. export default function ErrorMessage({
  13. error,
  14. }: {
  15. error: string | Record<string, any>
  16. }) {
  17. const { t } = useTranslation()
  18. const { isOverleaf } = getMeta('ol-ExposedSettings')
  19. const fileNameLimit = 150
  20. // the error is a string
  21. // TODO: translate? always? is this a key or a message?
  22. if (typeof error === 'string') {
  23. switch (error) {
  24. case 'name-exists':
  25. return <DangerMessage>{t('file_already_exists')}</DangerMessage>
  26. case 'too-many-files':
  27. return <DangerMessage>{t('project_has_too_many_files')}</DangerMessage>
  28. case 'remote-service-error':
  29. return <DangerMessage>{t('remote_service_error')}</DangerMessage>
  30. case 'folder_not_found':
  31. return (
  32. <DangerMessage>
  33. {t('the_target_folder_could_not_be_found')}
  34. </DangerMessage>
  35. )
  36. case 'invalid_filename':
  37. return (
  38. <DangerMessage>
  39. {t('invalid_filename', {
  40. nameLimit: fileNameLimit,
  41. })}
  42. </DangerMessage>
  43. )
  44. case 'invalid_upload_request':
  45. if (!isOverleaf) {
  46. return (
  47. <DangerMessage>{t('generic_something_went_wrong')}</DangerMessage>
  48. )
  49. }
  50. return (
  51. <DangerMessage>
  52. <Trans
  53. i18nKey="invalid_upload_request"
  54. // eslint-disable-next-line jsx-a11y/anchor-has-content, react/jsx-key
  55. components={[<a href="/contact" target="_blank" />]}
  56. />
  57. </DangerMessage>
  58. )
  59. case 'duplicate_file_name':
  60. return (
  61. <DangerMessage>
  62. {t('file_or_folder_name_already_exists')}
  63. </DangerMessage>
  64. )
  65. case 'rate-limit-hit':
  66. return (
  67. <DangerMessage>
  68. {t('too_many_files_uploaded_throttled_short_period')}
  69. </DangerMessage>
  70. )
  71. case 'not-logged-in':
  72. return (
  73. <DangerMessage>
  74. <RedirectToLogin />
  75. </DangerMessage>
  76. )
  77. case 'linked-project-compile-error':
  78. return (
  79. <DangerMessage>
  80. {t('generic_linked_file_compile_error')}
  81. </DangerMessage>
  82. )
  83. default:
  84. // TODO: convert error.response.data to an error key and try again?
  85. // return error
  86. return (
  87. <DangerMessage>{t('generic_something_went_wrong')}</DangerMessage>
  88. )
  89. }
  90. }
  91. // the error is an object
  92. // TODO: error.name?
  93. switch (error.constructor) {
  94. case FetchError: {
  95. const message = error.data?.message
  96. if (message) {
  97. return <DangerMessage>{message.text || message}</DangerMessage>
  98. }
  99. // TODO: translations
  100. switch (error.response?.status) {
  101. case 400:
  102. return <DangerMessage>{t('invalid_request')}</DangerMessage>
  103. case 403:
  104. return <DangerMessage>{t('session_error')}</DangerMessage>
  105. case 429:
  106. return <DangerMessage>{t('too_many_attempts')}</DangerMessage>
  107. default:
  108. return (
  109. <DangerMessage>{t('something_went_wrong_server')}</DangerMessage>
  110. )
  111. }
  112. }
  113. // these are handled by the filename input component
  114. case DuplicateFilenameError:
  115. case InvalidFilenameError:
  116. case BlockedFilenameError:
  117. return null
  118. // a generic error message
  119. default:
  120. // return error.message
  121. return <DangerMessage>{t('generic_something_went_wrong')}</DangerMessage>
  122. }
  123. }