Skip to content

Commit 1966a83

Browse files
committed
refactor: extract error logger helper
Signed-off-by: Adam Setch <[email protected]>
1 parent d1ba3ca commit 1966a83

17 files changed

+119
-50
lines changed

src/renderer/hooks/useNotifications.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { act, renderHook, waitFor } from '@testing-library/react';
22
import axios, { AxiosError } from 'axios';
33
import nock from 'nock';
44

5-
import log from 'electron-log';
65
import {
76
mockAuth,
87
mockGitHubCloudAccount,
@@ -14,10 +13,11 @@ import {
1413
mockSingleNotification,
1514
} from '../utils/api/__mocks__/response-mocks';
1615
import { Errors } from '../utils/errors';
16+
import * as logger from '../utils/logger';
1717
import { useNotifications } from './useNotifications';
1818

1919
describe('renderer/hooks/useNotifications.ts', () => {
20-
const logErrorSpy = jest.spyOn(log, 'error').mockImplementation();
20+
const logErrorSpy = jest.spyOn(logger, 'logError').mockImplementation();
2121

2222
beforeEach(() => {
2323
// axios will default to using the XHR adapter which can't be intercepted

src/renderer/hooks/useNotifications.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import log from 'electron-log';
21
import { useCallback, useState } from 'react';
32
import type {
43
Account,
@@ -14,6 +13,7 @@ import {
1413
markNotificationThreadAsRead,
1514
} from '../utils/api/client';
1615
import { isMarkAsDoneFeatureSupported } from '../utils/features';
16+
import { logError } from '../utils/logger';
1717
import {
1818
getAllNotifications,
1919
setTrayIconColor,
@@ -121,8 +121,9 @@ export const useNotifications = (): NotificationsState => {
121121
setNotifications(updatedNotifications);
122122
setTrayIconColor(updatedNotifications);
123123
} catch (err) {
124-
log.error(
125-
'[markNotificationsAsRead]: Error occurred while marking notifications as read',
124+
logError(
125+
'markNotificationsAsRead',
126+
'Error occurred while marking notifications as read',
126127
err,
127128
);
128129
}
@@ -158,8 +159,9 @@ export const useNotifications = (): NotificationsState => {
158159
setNotifications(updatedNotifications);
159160
setTrayIconColor(updatedNotifications);
160161
} catch (err) {
161-
log.error(
162-
'[markNotificationsAsDone]: error occurred while marking notifications as done',
162+
logError(
163+
'markNotificationsAsDone',
164+
'Error occurred while marking notifications as done',
163165
err,
164166
);
165167
}
@@ -186,9 +188,11 @@ export const useNotifications = (): NotificationsState => {
186188
await markNotificationsAsRead(state, [notification]);
187189
}
188190
} catch (err) {
189-
log.error(
190-
'[unsubscribeNotification]: error occurred while unsubscribing from notification thread',
191+
logError(
192+
'unsubscribeNotification',
193+
'Error occurred while unsubscribing from notification thread',
191194
err,
195+
notification,
192196
);
193197
}
194198

src/renderer/routes/Accounts.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import {
1111
SyncIcon,
1212
} from '@primer/octicons-react';
1313

14-
import log from 'electron-log';
1514
import { type FC, useCallback, useContext } from 'react';
1615
import { useNavigate } from 'react-router-dom';
1716
import { Header } from '../components/Header';
@@ -30,6 +29,7 @@ import {
3029
openDeveloperSettings,
3130
openHost,
3231
} from '../utils/links';
32+
import { logError } from '../utils/logger';
3333
import { saveState } from '../utils/storage';
3434

3535
export const AccountsRoute: FC = () => {
@@ -57,7 +57,7 @@ export const AccountsRoute: FC = () => {
5757
try {
5858
await loginWithGitHubApp();
5959
} catch (err) {
60-
log.error('Auth: failed to login with GitHub', err);
60+
logError('loginWithGitHub', 'failed to login with GitHub', err);
6161
}
6262
}, []);
6363

src/renderer/routes/Login.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
import { KeyIcon, MarkGithubIcon, PersonIcon } from '@primer/octicons-react';
2-
import log from 'electron-log';
32
import { type FC, useCallback, useContext, useEffect } from 'react';
43
import { useNavigate } from 'react-router-dom';
54
import { Button } from '../components/buttons/Button';
65
import { LogoIcon } from '../components/icons/LogoIcon';
76
import { AppContext } from '../context/App';
87
import { Size } from '../types';
98
import { showWindow } from '../utils/comms';
9+
import { logError } from '../utils/logger';
1010

1111
export const LoginRoute: FC = () => {
1212
const navigate = useNavigate();
@@ -23,7 +23,7 @@ export const LoginRoute: FC = () => {
2323
try {
2424
await loginWithGitHubApp();
2525
} catch (err) {
26-
log.error('Auth: failed to login with GitHub', err);
26+
logError('loginWithGitHubApp', 'failed to login with GitHub', err);
2727
}
2828
}, [loginWithGitHubApp]);
2929

src/renderer/routes/LoginWithOAuthApp.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { BookIcon, PersonIcon, SignInIcon } from '@primer/octicons-react';
2-
import log from 'electron-log';
32
import { type FC, useCallback, useContext } from 'react';
43
import { Form, type FormRenderProps } from 'react-final-form';
54
import { useNavigate } from 'react-router-dom';
@@ -22,6 +21,7 @@ import {
2221
isValidToken,
2322
} from '../utils/auth/utils';
2423
import { Constants } from '../utils/constants';
24+
import { logError } from '../utils/logger';
2525

2626
interface IValues {
2727
hostname?: Hostname;
@@ -131,7 +131,7 @@ export const LoginWithOAuthAppRoute: FC = () => {
131131
await loginWithOAuthApp(data as LoginOAuthAppOptions);
132132
navigate(-1);
133133
} catch (err) {
134-
log.error('Auth: Failed to login with oauth app', err);
134+
logError('loginWithOAuthApp', 'Failed to login with OAuth App', err);
135135
}
136136
},
137137
[loginWithOAuthApp],

src/renderer/routes/LoginWithPersonalAccessToken.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { BookIcon, KeyIcon, SignInIcon } from '@primer/octicons-react';
2-
import log from 'electron-log';
32
import { type FC, useCallback, useContext, useState } from 'react';
43
import { Form, type FormRenderProps } from 'react-final-form';
54
import { useNavigate } from 'react-router-dom';
@@ -15,6 +14,7 @@ import {
1514
isValidToken,
1615
} from '../utils/auth/utils';
1716
import { Constants } from '../utils/constants';
17+
import { logError } from '../utils/logger';
1818

1919
interface IValues {
2020
token?: Token;
@@ -129,7 +129,11 @@ export const LoginWithPersonalAccessTokenRoute: FC = () => {
129129
);
130130
navigate(-1);
131131
} catch (err) {
132-
log.error('Auth: failed to login with personal access token', err);
132+
logError(
133+
'loginWithPersonalAccessToken',
134+
'Failed to login with PAT',
135+
err,
136+
);
133137
setIsValidToken(false);
134138
}
135139
},

src/renderer/utils/api/client.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import axios, { type AxiosPromise, type AxiosResponse } from 'axios';
2-
import log from 'electron-log';
32
import {
43
mockGitHubCloudAccount,
54
mockGitHubEnterpriseServerAccount,
65
mockToken,
76
} from '../../__mocks__/state-mocks';
87
import type { Hostname, Link, SettingsState, Token } from '../../types';
8+
import * as logger from '../logger';
99
import {
1010
getAuthenticatedUser,
1111
getHtmlUrl,
@@ -268,7 +268,7 @@ describe('renderer/utils/api/client.ts', () => {
268268
});
269269

270270
it('should handle error', async () => {
271-
const logErrorSpy = jest.spyOn(log, 'error').mockImplementation();
271+
const logErrorSpy = jest.spyOn(logger, 'logError').mockImplementation();
272272

273273
const apiRequestAuthMock = jest.spyOn(apiRequests, 'apiRequestAuth');
274274

src/renderer/utils/api/client.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import type { AxiosPromise } from 'axios';
2-
import log from 'electron-log';
32
import { print } from 'graphql/language/printer';
43
import type {
54
Account,
@@ -23,6 +22,7 @@ import type {
2322
UserDetails,
2423
} from '../../typesGitHub';
2524
import { isAnsweredDiscussionFeatureSupported } from '../features';
25+
import { logError } from '../logger';
2626
import { QUERY_SEARCH_DISCUSSIONS } from './graphql/discussions';
2727
import { formatAsGitHubSearchSyntax } from './graphql/utils';
2828
import { apiRequestAuth } from './request';
@@ -217,9 +217,9 @@ export async function getHtmlUrl(url: Link, token: Token): Promise<string> {
217217
const response = (await apiRequestAuth(url, 'GET', token)).data;
218218
return response.html_url;
219219
} catch (err) {
220-
log.error(
221-
'[getHtmlUrl]: error occurred while fetching html url for',
222-
url,
220+
logError(
221+
'getHtmlUrl',
222+
`error occurred while fetching html url for ${url}`,
223223
err,
224224
);
225225
}
@@ -271,10 +271,11 @@ export async function getLatestDiscussion(
271271
)[0] ?? null
272272
);
273273
} catch (err) {
274-
log.error(
275-
'[getLatestDiscussion]: failed to fetch latest discussion for notification',
276-
`[${notification.subject.type}]: ${notification.subject.title} for repository ${notification.repository.full_name}`,
274+
logError(
275+
'getLatestDiscussion',
276+
'failed to fetch latest discussion for notification',
277277
err,
278+
notification,
278279
);
279280
}
280281
}

src/renderer/utils/api/request.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import axios, {
33
type AxiosPromise,
44
type Method,
55
} from 'axios';
6-
import log from 'electron-log';
76
import type { Link, Token } from '../../types';
7+
import { logError } from '../logger';
88
import { getNextURLFromLinkHeader } from './utils';
99

1010
/**
@@ -73,7 +73,8 @@ export async function apiRequestAuth(
7373
nextUrl = getNextURLFromLinkHeader(response);
7474
}
7575
} catch (err) {
76-
log.error('[apiRequestAuth]: API request failed:', err);
76+
logError('apiRequestAuth', 'API request failed:', err);
77+
7778
throw err;
7879
}
7980

src/renderer/utils/auth/utils.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { BrowserWindow } from '@electron/remote';
22
import { format } from 'date-fns';
3-
import log from 'electron-log';
43
import semver from 'semver';
54
import type {
65
Account,
@@ -17,6 +16,7 @@ import { getAuthenticatedUser } from '../api/client';
1716
import { apiRequest } from '../api/request';
1817
import { Constants } from '../constants';
1918
import { getPlatformFromHostname } from '../helpers';
19+
import { logError } from '../logger';
2020
import type { AuthMethod, AuthResponse, AuthTokenResponse } from './types';
2121

2222
// TODO - Refactor our OAuth2 flow to use system browser and local app gitify://callback - see #485 #561 #654
@@ -178,9 +178,9 @@ export async function refreshAccount(account: Account): Promise<Account> {
178178
accountScopes.includes(scope),
179179
);
180180
} catch (err) {
181-
log.error(
182-
'[refreshAccount]: failed to refresh account for user',
183-
account.user.login,
181+
logError(
182+
'refreshAccount',
183+
`failed to refresh account for user ${account.user.login}`,
184184
err,
185185
);
186186
}

0 commit comments

Comments
 (0)