about summary refs log tree commit diff
path: root/src/lib/hooks/useCleanError.ts
blob: 3b7b575bce0040ba41f45a2fa8d0d24ac661b745 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import {useCallback} from 'react'
import {msg} from '@lingui/macro'
import {useLingui} from '@lingui/react'

type CleanedError = {
  raw: string | undefined
  clean: string | undefined
}

export function useCleanError() {
  const {_} = useLingui()

  return useCallback<(error?: any) => CleanedError>(
    error => {
      if (!error)
        return {
          raw: undefined,
          clean: undefined,
        }

      let raw = error.toString()

      if (isNetworkError(raw)) {
        return {
          raw,
          clean: _(
            msg`Unable to connect. Please check your internet connection and try again.`,
          ),
        }
      }

      if (
        raw.includes('Upstream Failure') ||
        raw.includes('NotEnoughResources') ||
        raw.includes('pipethrough network error')
      ) {
        return {
          raw,
          clean: _(
            msg`The server appears to be experiencing issues. Please try again in a few moments.`,
          ),
        }
      }

      if (raw.includes('Bad token scope') || raw.includes('Bad token method')) {
        return {
          raw,
          clean: _(
            msg`This feature is not available while using an app password. Please sign in with your main password.`,
          ),
        }
      }

      if (raw.includes('Rate Limit Exceeded')) {
        return {
          raw,
          clean: _(
            msg`You've reached the maximum number of requests allowed. Please try again later.`,
          ),
        }
      }

      if (raw.startsWith('Error: ')) {
        raw = raw.slice('Error: '.length)
      }

      return {
        raw,
        clean: undefined,
      }
    },
    [_],
  )
}

const NETWORK_ERRORS = [
  'Abort',
  'Network request failed',
  'Failed to fetch',
  'Load failed',
]

export function isNetworkError(e: unknown) {
  const str = String(e)
  for (const err of NETWORK_ERRORS) {
    if (str.includes(err)) {
      return true
    }
  }
  return false
}