Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export const handleActionError = (error, source) => dispatch => {
// On production we send the errors to Sentry.
// eslint-disable-next-line no-console
if (window.app.env !== 'production') console.error(error, error.stack);
// logout when unauthorized
if (error.statusCode === STATUS_CODES.UNAUTHORIZED) {
browserHistory.push(`/logout?reason=${LOGOUT_REASONS.UNAUTHORIZED}`);
}
// We need to do the return, because if not we see an error notification
// The error is handled with the handleUnavailableResource HoC to show the PageNotFound component
// when the api returns 404
if (error.statusCode === STATUS_CODES.NOT_FOUND) return null;
// All native errors that might occur within a Promise handler,
// are caught here as well. In this case we dispatch an unexpected
// error notification.
if (!error.statusCode)
return dispatch(showUnexpectedErrorNotification({ source, error }));
const hasListOfErrors = error.body.errors && Array.isArray(error.body.errors);
return dispatch(
showApiErrorNotification({
return (
dispatch: Dispatch<
| ReturnType
| ReturnType
>
) => {
// On production we send the errors to Sentry.
// eslint-disable-next-line no-console
if (window.app.env !== 'production')
console.error(error, error instanceof Error && error.stack);
if (!isApiError(error)) return dispatch(showUnexpectedErrorNotification());
// logout when unauthorized
if (error.statusCode === STATUS_CODES.UNAUTHORIZED) {
browserHistory.push(`/logout?reason=${LOGOUT_REASONS.UNAUTHORIZED}`);
}
// We need to do the return, because if not we see an error notification
// The error is handled with the handleUnavailableResource HoC to show the PageNotFound component
// when the api returns 404
if (error.statusCode === STATUS_CODES.NOT_FOUND) return null;
return dispatch(
showApiErrorNotification({
errors: error.body.errors || [
// Pass a fallback error so that our error components can handle it
{ message: error.body.message },
],
})
);
};
if (process.env.NODE_ENV !== 'production')
if (notification.domain) {
if (!Object.values(NOTIFICATION_DOMAINS).includes(notification.domain))
// eslint-disable-next-line no-console
console.warn(
`Unknown notification domain "${notification.domain}"`,
notification
);
}
// eslint-disable-next-line no-console
else console.warn('Notification is missing domain', notification);
let dismissAfter = meta.dismissAfter;
if (!isNumber(dismissAfter))
dismissAfter =
notification.kind === NOTIFICATION_KINDS_SIDE.success ? 5000 : 0;
return addNotification>(notification, {
...meta,
dismissAfter,
});
}
return (
dispatch: Dispatch<
| ReturnType
| ReturnType
>
) => {
// On production we send the errors to Sentry.
// eslint-disable-next-line no-console
if (window.app.env !== 'production')
console.error(error, error instanceof Error && error.stack);
if (!isApiError(error)) return dispatch(showUnexpectedErrorNotification());
// logout when unauthorized
if (error.statusCode === STATUS_CODES.UNAUTHORIZED) {
browserHistory.push(`/logout?reason=${LOGOUT_REASONS.UNAUTHORIZED}`);
}
// We need to do the return, because if not we see an error notification
// The error is handled with the handleUnavailableResource HoC to show the PageNotFound component
// when the api returns 404
if (error.statusCode === STATUS_CODES.NOT_FOUND) return null;
return dispatch(
showApiErrorNotification({
errors: error.body.errors || [
// Pass a fallback error so that our error components can handle it
{ message: error.body.message },
],
})
);
export const handleActionError = (error, source) => dispatch => {
// On production we send the errors to Sentry.
// eslint-disable-next-line no-console
if (window.app.env !== 'production') console.error(error, error.stack);
// logout when unauthorized
if (error.statusCode === STATUS_CODES.UNAUTHORIZED) {
browserHistory.push(`/logout?reason=${LOGOUT_REASONS.UNAUTHORIZED}`);
}
// We need to do the return, because if not we see an error notification
// The error is handled with the handleUnavailableResource HoC to show the PageNotFound component
// when the api returns 404
if (error.statusCode === STATUS_CODES.NOT_FOUND) return null;
// All native errors that might occur within a Promise handler,
// are caught here as well. In this case we dispatch an unexpected
// error notification.
if (!error.statusCode)
return dispatch(showUnexpectedErrorNotification({ source, error }));
const hasListOfErrors = error.body.errors && Array.isArray(error.body.errors);
return dispatch(
export function showApiErrorNotification({ errors, source }) {
return showNotification(
{
kind: 'api-error',
values: {
source,
// NOTE: Some sources or errors (e.g. GraphQL) return an array or object.
// The cast into an array happens here so that consumers can pass both types.
errors: Array.isArray(errors) ? errors : [errors],
},
domain: DOMAINS.PAGE,
},
{
dismissAfter: 0,
}
);
}
export default function showApiErrorNotification({
errors,
}: TApiErrorNotificationOptions) {
return showNotification(
{
id: 0,
domain: DOMAINS.PAGE,
kind: 'api-error',
values: {
// NOTE: Some sources or errors (e.g. GraphQL) return an array or object.
// The cast into an array happens here so that consumers can pass both types.
errors: Array.isArray(errors) ? errors : [errors],
},
},
{
dismissAfter: 0,
}
);
}
({ graphQLErrors, networkError, operation, forward }) => {
if (networkError && networkError.statusCode === STATUS_CODES.UNAUTHORIZED) {
history.push(`/logout?reason=${LOGOUT_REASONS.UNAUTHORIZED}`);
}
// In case of graphql errors, we want to retry unauthenticated requests by
// forcing our API to fetch a new token, using the `X-Force-Token` header.
// https://www.apollographql.com/docs/link/links/error/#retrying-failed-requests
// We need to do this as the `token-retry-link` only works for network errors.
// https://www.apollographql.com/docs/link/links/retry/
if (graphQLErrors) {
for (const err of graphQLErrors) {
if (err.extensions && err.extensions.code === 'UNAUTHENTICATED') {
operation.setContext(({ headers }) => ({
headers: {
...headers,
'X-Force-Token': true,
},
}));
// retry the request, returning the new observable
role="application-layout"
css={css`
height: 100vh;
display: grid;
grid-template-rows: auto 43px 1fr;
grid-template-columns: auto 1fr;
`}
>
<div role="global-notifications">
</div>
{() => {
if (!projectKeyFromUrl) return ;
return (
{({ isLoading: isProjectLoading, project }) => {
if (isProjectLoading) return null;
// when used outside of a project context,
// or when the project is expired or supsended
const useProjectContext =
project &&
!(
(project.suspension &&
background-color: ${props.fixed
? 'transparent'
: getColorByType(props.type)};
> * + * {
margin-left: ${customProperties.spacingS};
}
`;
switch (props.domain) {
case NOTIFICATION_DOMAINS.GLOBAL:
return css`
${pageStyles};
background-color: ${getColorByType(props.type)};
`;
case NOTIFICATION_DOMAINS.PAGE:
return pageStyles;
case NOTIFICATION_DOMAINS.SIDE: {
const sideStyles = css`
${baseStyles};
animation: ${showNotificationAnimation} 0.3s forwards;
padding: ${customProperties.spacingM} ${customProperties.spacingM}
${customProperties.spacingM} 50px !important;
text-align: left;
background: ${customProperties.colorSurface};
border: 1px solid ${getColorByType(props.type)};
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.24);
border-radius: ${customProperties.borderRadius6};
word-break: break-word;
hyphens: auto; /* still not supported on Chrome */
`;