Skip to content

Commit

Permalink
Merge pull request #188 from mareklibra/sentry
Browse files Browse the repository at this point in the history
Add Sentry exception logging
  • Loading branch information
Jiri Tomasek authored Sep 9, 2020
2 parents 9fa4daa + 8c3dc7d commit 1b833fb
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 13 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@patternfly/react-table": "^4.15.5",
"@patternfly/react-tokens": "^4.9.4",
"@reduxjs/toolkit": "^1.3.5",
"@sentry/browser": "5.19.1",
"axios": "^0.19.2",
"file-saver": "^2.0.2",
"formik": "^2.1.4",
Expand Down
4 changes: 2 additions & 2 deletions src/api/useApi.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import { AxiosPromise } from 'axios';
import { ResourceUIState } from '../types';
import { captureException } from '../sentry';

type ApiCall<P, T> = (params: P) => AxiosPromise<T>;

Expand Down Expand Up @@ -56,8 +57,7 @@ const fetchData = async <P, D>(
const { data } = await apiCall(params!); // eslint-disable-line @typescript-eslint/no-non-null-assertion
dispatch({ type: 'SUCCESS', payload: data });
} catch (e) {
console.error(e);
console.error('Response data:', e.response?.data);
captureException(e);
dispatch({ type: 'ERROR' });
}
};
Expand Down
16 changes: 9 additions & 7 deletions src/api/utils.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
import Axios, { AxiosError } from 'axios';
import _ from 'lodash';
import { captureException } from '../sentry';

type OnError = <T>(arg0: AxiosError<T>) => void;

export const handleApiError = <T>(error: AxiosError<T>, onError?: OnError) => {
if (Axios.isCancel(error)) {
console.error('Request canceled:', error.message);
captureException(error, 'Request canceled');
} else {
let message = `Error config: ${error.config}\n`;
if (error.response) {
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
console.error('Response data:', error.response.data);
console.error('Response status:', error.response.status);
console.error('Response headers:', error.response.headers);
message += `Response data: ${error.response.data}\n`;
message += `Response status: ${error.response.status}\n`;
message += `Response headers: ${error.response.headers}`;
} 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('Request:', error.request);
message += `Request: ${error.request}`;
} else {
// Something happened in setting up the request that triggered an Error
console.error('Error', error.message);
message += `Error: ${error.message}`;
}
console.error('Error config:', error.config);
captureException(error, message);
if (onError) return onError(error);
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import ClusterValidationSection from './ClusterValidationSection';
import { getInitialValues, getHostSubnets } from './utils';
import { AlertsContext } from '../AlertsContextProvider';
import ClusterSshKeyField from './ClusterSshKeyField';
import { captureException } from '../../sentry';

const validationSchema = (initialValues: ClusterConfigurationValues, hostSubnets: HostSubnets) =>
Yup.lazy<ClusterConfigurationValues>((values) =>
Expand Down Expand Up @@ -98,7 +99,7 @@ const ClusterConfigurationForm: React.FC<ClusterConfigurationFormProps> = ({
return formikActions.setFieldError('name', `Name "${values.name}" is already taken.`);
}
} catch (e) {
console.error('Failed to perform unique cluster name validation.', e);
captureException('Failed to perform unique cluster name validation.', e);
}

// update the cluster configuration
Expand Down
3 changes: 2 additions & 1 deletion src/components/clusters/NewClusterPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import InputField from '../ui/formik/InputField';
import SelectField from '../ui/formik/SelectField';
import TextAreaField from '../ui/formik/TextAreaField';
import LoadingState from '../ui/uiState/LoadingState';
import { captureException } from '../../sentry';

const pullSecretHelperText = (
<>
Expand Down Expand Up @@ -81,7 +82,7 @@ const NewClusterForm: React.FC<NewClusterFormProps> = ({ history, pullSecret = '
return formikActions.setFieldError('name', `Name "${values.name}" is already taken.`);
}
} catch (e) {
console.error('Failed to perform unique cluster name validation.', e);
captureException(e, 'Failed to perform unique cluster name validation.');
}

try {
Expand Down
6 changes: 4 additions & 2 deletions src/components/fetching/EventListFetch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getEvents } from '../../api/clusters';
import { EVENTS_POLLING_INTERVAL } from '../../config/constants';
import { ErrorState, LoadingState } from '../ui/uiState';
import ClusterEventsList from '../ui/ClusterEventsList';
import { handleApiError } from '../../api';

export type EventFetchProps = {
hostId: Event['hostId'];
Expand All @@ -30,8 +31,9 @@ const EventListFetch: React.FC<EventListFetchProps> = ({ cluster, hostId, entity
setEvents(data);
setError('');
} catch (error) {
console.warn(`Failed to load events for ${entityKind} ${hostId || cluster.id}: `, error);
setError('Failed to load events');
handleApiError(error, () => {
setError('Failed to load events');
});
}
timer = setTimeout(() => setLastPolling(Date.now()), EVENTS_POLLING_INTERVAL);
};
Expand Down
18 changes: 18 additions & 0 deletions src/sentry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import * as Sentry from '@sentry/browser';
import { ocmClient } from './api/axiosClient';

export enum SEVERITY {
ERROR = 'error',
WARN = 'warning',
}

// eslint-disable-next-line @typescript-eslint/ban-ts-ignore
// @ts-ignore
export const captureException = (error, message?: string, severity: SEVERITY = SEVERITY.ERROR) => {
if (ocmClient) {
message && Sentry.captureMessage(message, SEVERITY[severity]);
Sentry.captureException(error);
} else {
severity === SEVERITY.ERROR ? console.error(message, error) : console.warn(message, error);
}
};

0 comments on commit 1b833fb

Please sign in to comment.