1
0
mirror of https://github.com/tooot-app/app synced 2025-02-26 00:27:44 +01:00

Refine error logging

Previous attempt resulted in truncated error object which is not readable
This commit is contained in:
xmflsct 2022-12-05 19:24:03 +01:00
parent db6ef36278
commit 210b34304c
6 changed files with 75 additions and 54 deletions

View File

@ -22,13 +22,13 @@ const apiGeneral = async <T = unknown>({
}: Params): Promise<{ body: T }> => { }: Params): Promise<{ body: T }> => {
console.log( console.log(
ctx.bgGreen.bold(' API general ') + ctx.bgGreen.bold(' API general ') +
' ' + ' ' +
domain + domain +
' ' + ' ' +
method + method +
ctx.green(' -> ') + ctx.green(' -> ') +
`/${url}` + `/${url}` +
(params ? ctx.green(' -> ') : ''), (params ? ctx.green(' -> ') : ''),
params ? params : '' params ? params : ''
) )
@ -39,10 +39,7 @@ const apiGeneral = async <T = unknown>({
url, url,
params, params,
headers: { headers: {
'Content-Type': 'Content-Type': body && body instanceof FormData ? 'multipart/form-data' : 'application/json',
body && body instanceof FormData
? 'multipart/form-data'
: 'application/json',
Accept: '*/*', Accept: '*/*',
...userAgent, ...userAgent,
...headers ...headers
@ -54,7 +51,7 @@ const apiGeneral = async <T = unknown>({
body: response.data body: response.data
}) })
}) })
.catch(handleError) .catch(handleError())
} }
export default apiGeneral export default apiGeneral

View File

@ -1,3 +1,4 @@
import * as Sentry from '@sentry/react-native'
import chalk from 'chalk' import chalk from 'chalk'
import Constants from 'expo-constants' import Constants from 'expo-constants'
import { Platform } from 'react-native' import { Platform } from 'react-native'
@ -7,30 +8,59 @@ const userAgent = {
} }
const ctx = new chalk.Instance({ level: 3 }) const ctx = new chalk.Instance({ level: 3 })
const handleError = (error: any) => { const handleError =
if (error?.response) { (
// The request was made and the server responded with a status code config: {
// that falls out of the range of 2xx message: string
console.error( captureRequest?: { url: string; params: any; body: any }
ctx.bold(' API '), captureResponse?: boolean
ctx.bold('response'), } | void
error.response.status, ) =>
error?.response.data?.error || error?.response.message || 'Unknown error' (error: any) => {
) const shouldReportToSentry = config && (config.captureRequest || config.captureResponse)
return Promise.reject({ shouldReportToSentry && Sentry.setContext('Error object', error)
status: error?.response.status,
message: error?.response.data?.error || error?.response.message || 'Unknown error' if (config?.captureRequest) {
}) Sentry.setContext('Error request', config.captureRequest)
} else if (error?.request) { }
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of if (error?.response) {
// http.ClientRequest in node.js if (config?.captureResponse) {
console.error(ctx.bold(' API '), ctx.bold('request'), error) Sentry.setContext('Error response', {
return Promise.reject() data: error.response.data,
} else { status: error.response.status,
console.error(ctx.bold(' API '), ctx.bold('internal'), error?.message) headers: error.response.headers
return Promise.reject() })
}
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error(
ctx.bold(' API '),
ctx.bold('response'),
error.response.status,
error?.response.data?.error || error?.response.message || 'Unknown error'
)
shouldReportToSentry && Sentry.captureMessage(config.message)
return Promise.reject({
status: error?.response.status,
message: error?.response.data?.error || error?.response.message || 'Unknown error'
})
} else if (error?.request) {
// The request was made but no response was received
// `error.request` is an instance of XMLHttpRequest in the browser and an instance of
// http.ClientRequest in node.js
console.error(ctx.bold(' API '), ctx.bold('request'), error)
shouldReportToSentry && Sentry.captureMessage(config.message)
return Promise.reject()
} else {
console.error(ctx.bold(' API '), ctx.bold('internal'), error?.message)
shouldReportToSentry && Sentry.captureMessage(config.message)
return Promise.reject()
}
} }
}
export { ctx, handleError, userAgent } export { ctx, handleError, userAgent }

View File

@ -86,7 +86,7 @@ const apiInstance = async <T = unknown>({
links: { prev, next } links: { prev, next }
}) })
}) })
.catch(handleError) .catch(handleError())
} }
export default apiInstance export default apiInstance

View File

@ -55,16 +55,13 @@ const apiTooot = async <T = unknown>({
body: response.data body: response.data
}) })
}) })
.catch(error => { .catch(
Sentry.setContext('API request', { url, params, body }) handleError({
Sentry.setContext('Error response', { message: 'API error',
...(error?.response && { response: error.response?._response }) captureRequest: { url, params, body },
captureResponse: true
}) })
Sentry.setContext('Error object', { error }) )
Sentry.captureMessage('API error')
return handleError(error)
})
} }
export default apiTooot export default apiTooot

View File

@ -1,3 +1,4 @@
import { handleError } from '@api/helpers'
import { ComponentEmojis } from '@components/Emojis' import { ComponentEmojis } from '@components/Emojis'
import { EmojisState } from '@components/Emojis/helpers/EmojisContext' import { EmojisState } from '@components/Emojis/helpers/EmojisContext'
import { HeaderLeft, HeaderRight } from '@components/Header' import { HeaderLeft, HeaderRight } from '@components/Header'
@ -6,7 +7,6 @@ import haptics from '@root/components/haptics'
import { useAppDispatch } from '@root/store' import { useAppDispatch } from '@root/store'
import ComposeRoot from '@screens/Compose/Root' import ComposeRoot from '@screens/Compose/Root'
import formatText from '@screens/Compose/utils/formatText' import formatText from '@screens/Compose/utils/formatText'
import * as Sentry from '@sentry/react-native'
import { RootStackScreenProps } from '@utils/navigation/navigators' import { RootStackScreenProps } from '@utils/navigation/navigators'
import { useTimelineMutation } from '@utils/queryHooks/timeline' import { useTimelineMutation } from '@utils/queryHooks/timeline'
import { updateStoreReview } from '@utils/slices/contextsSlice' import { updateStoreReview } from '@utils/slices/contextsSlice'
@ -319,9 +319,8 @@ const ScreenCompose: React.FC<RootStackScreenProps<'Screen-Compose'>> = ({
] ]
) )
} else { } else {
Sentry.setContext('Error object', { error })
Sentry.captureMessage('Posting error')
haptics('Error') haptics('Error')
handleError({ message: 'Posting error', captureResponse: true })
composeDispatch({ type: 'posting', payload: false }) composeDispatch({ type: 'posting', payload: false })
Alert.alert(t('heading.right.alert.default.title'), undefined, [ Alert.alert(t('heading.right.alert.default.title'), undefined, [
{ {

View File

@ -1,4 +1,5 @@
import apiGeneral from '@api/general' import apiGeneral from '@api/general'
import { handleError } from '@api/helpers'
import apiTooot from '@api/tooot' import apiTooot from '@api/tooot'
import { displayMessage } from '@components/Message' import { displayMessage } from '@components/Message'
import navigationRef from '@helpers/navigationRef' import navigationRef from '@helpers/navigationRef'
@ -33,11 +34,8 @@ const pushUseConnect = () => {
}) })
.then(() => Notifications.setBadgeCountAsync(0)) .then(() => Notifications.setBadgeCountAsync(0))
.catch(error => { .catch(error => {
Sentry.setContext('Error response', { handleError({ message: 'Push connect error', captureResponse: true })
...(error?.response && { response: error.response?._response })
})
Sentry.setContext('Error object', { error })
Sentry.captureMessage('Push connect error')
Notifications.setBadgeCountAsync(0) Notifications.setBadgeCountAsync(0)
if (error?.status == 404) { if (error?.status == 404) {
displayMessage({ displayMessage({