Fix reported errors by Faro (#4408)
# What this PR does Fixes the following reported errors by Faro - Cannot read properties of undefined (reading 'error_code') - found in Page Error Handling wrapper - Cannot read properties of undefined (reading 'slack_team_identity') - Found in DefaultPageLayout helpers - Cannot read properties of undefined (reading 'reduce') - undefined passed labels in labels helpers - Cannot read properties of undefined (reading 'controlled_fields') - webhooks - Cannot read properties of undefined (reading 'data') The following needs to be further investigated to see if the response misses whole body - Cannot read properties of undefined (reading 'config') - happening in Faro. I assume it's when an exception is thrown and the ex doesn't have the `config` field ## Which issue(s) this PR closes Closes #4403
This commit is contained in:
parent
7e3008ba0f
commit
80ecde6fbb
13 changed files with 28 additions and 50 deletions
|
|
@ -8,7 +8,7 @@ export function getWrongTeamResponseInfo(response): Partial<PageErrorData> {
|
|||
if (response) {
|
||||
if (response.status === 404) {
|
||||
return { isNotFoundError: true };
|
||||
} else if (response.status === 403 && response.data.error_code === 'wrong_team') {
|
||||
} else if (response.status === 403 && response.data?.error_code === 'wrong_team') {
|
||||
let res = response.data;
|
||||
if (res.owner_team) {
|
||||
return { isWrongTeamError: true, switchToTeam: { name: res.owner_team.name, id: res.owner_team.id } };
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import React from 'react';
|
||||
|
||||
import { PluginLink } from 'components/PluginLink/PluginLink';
|
||||
import { RenderConditionally } from 'components/RenderConditionally/RenderConditionally';
|
||||
import { Organization } from 'models/organization/organization.types';
|
||||
|
||||
import { SlackError } from './DefaultPageLayout.types';
|
||||
|
|
@ -10,12 +11,15 @@ export function getSlackMessage(slackError: SlackError, organization: Organizati
|
|||
return (
|
||||
<>
|
||||
Couldn't connect Slack.
|
||||
{Boolean(organization?.slack_team_identity) && (
|
||||
<>
|
||||
{' '}
|
||||
Select <b>{organization.slack_team_identity.cached_name}</b> workspace when connecting please
|
||||
</>
|
||||
)}
|
||||
<RenderConditionally
|
||||
shouldRender={Boolean(organization?.slack_team_identity)}
|
||||
render={() => (
|
||||
<>
|
||||
{' '}
|
||||
Select <b>{organization.slack_team_identity.cached_name}</b> workspace when connecting please
|
||||
</>
|
||||
)}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ function prepareDataForEdit(
|
|||
|
||||
function prepareForSave(rawData: Partial<ApiSchemas['Webhook']>, selectedPreset: OutgoingWebhookPreset) {
|
||||
const data = { ...rawData };
|
||||
selectedPreset.controlled_fields.forEach((field) => {
|
||||
selectedPreset?.controlled_fields.forEach((field) => {
|
||||
delete data[field];
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ export const OutgoingWebhookFormFields = ({
|
|||
return (
|
||||
<>
|
||||
{React.Children.toArray(controls.props.children).filter(
|
||||
(child) => !preset || !preset.controlled_fields.includes((child as React.ReactElement).props.name)
|
||||
(child) => !preset?.controlled_fields.includes((child as React.ReactElement).props.name)
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export const additionalWebhookPresetIcons: { [id: string]: () => React.ReactElem
|
|||
};
|
||||
|
||||
export const getWebhookPresetIcons = (features: Record<string, boolean>) => {
|
||||
if (features[AppFeature.MsTeams]) {
|
||||
if (features?.[AppFeature.MsTeams]) {
|
||||
return { ...commonWebhookPresetIconsConfig, ...additionalWebhookPresetIcons };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -202,9 +202,11 @@ export const RotationForm = observer((props: RotationFormProps) => {
|
|||
}
|
||||
};
|
||||
|
||||
const onError = useCallback((error) => {
|
||||
setErrors(error.response.data);
|
||||
}, []);
|
||||
const onError = (error) => {
|
||||
if (error.response?.data) {
|
||||
setErrors(error.response.data);
|
||||
}
|
||||
};
|
||||
|
||||
const handleChange = useDebouncedCallback(updatePreview, 200);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export const ScheduleUserDetails: FC<ScheduleUserDetailsProps> = observer((props
|
|||
|
||||
const { organizationStore } = store;
|
||||
const slackWorkspaceName =
|
||||
organizationStore.currentOrganization.slack_team_identity?.cached_name?.replace(/[^0-9a-z]/gi, '') || '';
|
||||
organizationStore.currentOrganization?.slack_team_identity?.cached_name?.replace(/[^0-9a-z]/gi, '') || '';
|
||||
|
||||
return (
|
||||
<div className={cx('root')} data-testid="schedule-user-details">
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ export class EscalationChainStore extends BaseStore {
|
|||
try {
|
||||
escalationChain = await this.getById(id, skipErrorHandling);
|
||||
} catch (error) {
|
||||
if (error.response.data.error_code === 'wrong_team') {
|
||||
if (error.response.data?.error_code === 'wrong_team') {
|
||||
escalationChain = {
|
||||
id,
|
||||
name: '🔒 Private escalation chain',
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { ApiSchemas } from 'network/oncall-api/api.types';
|
||||
|
||||
export const splitToGroups = (labels: Array<ApiSchemas['LabelKey']> | Array<ApiSchemas['LabelValue']>) => {
|
||||
return labels.reduce(
|
||||
return labels?.reduce(
|
||||
(memo, option) => {
|
||||
memo.find(({ name }) => name === (option.prescribed ? 'System' : 'User added')).options.push(option);
|
||||
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ export class ScheduleStore extends BaseStore {
|
|||
try {
|
||||
schedule = await this.getById(id, true, fromOrganization);
|
||||
} catch (error) {
|
||||
if (error.response.data.error_code === 'wrong_team') {
|
||||
if (error.response.data?.error_code === 'wrong_team') {
|
||||
schedule = {
|
||||
id,
|
||||
name: '🔒 Private schedule',
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
<div className={cx('root')}>
|
||||
<Legend>Slack App settings</Legend>
|
||||
<InlineField label="Slack Workspace" grow disabled>
|
||||
<Input value={currentOrganization.slack_team_identity?.cached_name} />
|
||||
<Input value={currentOrganization?.slack_team_identity?.cached_name} />
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default channel for Slack notifications"
|
||||
|
|
@ -203,34 +203,6 @@ class _SlackSettings extends Component<SlackProps, SlackState> {
|
|||
);
|
||||
};
|
||||
|
||||
renderSlackWorkspace = () => {
|
||||
const { store } = this.props;
|
||||
return <Text>{store.organizationStore.currentOrganization.slack_team_identity?.cached_name}</Text>;
|
||||
};
|
||||
|
||||
renderSlackChannels = () => {
|
||||
const {
|
||||
store: { organizationStore, slackChannelStore },
|
||||
} = this.props;
|
||||
return (
|
||||
<WithPermissionControlTooltip userAction={UserActions.ChatOpsUpdateSettings}>
|
||||
<GSelect<SlackChannel>
|
||||
className={cx('select', 'control')}
|
||||
items={slackChannelStore.items}
|
||||
fetchItemsFn={slackChannelStore.updateItems}
|
||||
fetchItemFn={slackChannelStore.updateItem}
|
||||
getSearchResult={slackChannelStore.getSearchResult}
|
||||
displayField="display_name"
|
||||
valueField="id"
|
||||
placeholder="Select Slack Channel"
|
||||
value={organizationStore.currentOrganization?.slack_channel?.id}
|
||||
onChange={this.handleSlackChannelChange}
|
||||
nullItemName={PRIVATE_CHANNEL_NAME}
|
||||
/>
|
||||
</WithPermissionControlTooltip>
|
||||
);
|
||||
};
|
||||
|
||||
removeSlackIntegration = async () => {
|
||||
const { store } = this.props;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ class Users extends React.Component<UsersProps, UsersState> {
|
|||
warnings.push('Phone not verified');
|
||||
}
|
||||
|
||||
if (organizationStore.currentOrganization.slack_team_identity && !user.slack_user_identity) {
|
||||
if (organizationStore.currentOrganization?.slack_team_identity && !user.slack_user_identity) {
|
||||
warnings.push('Slack profile is not connected');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -99,17 +99,17 @@ class BaseFaroHelper {
|
|||
|
||||
pushAxiosNetworkResponseEvent = ({ name, res }: { name: string; res: AxiosResponse }) => {
|
||||
this.faro?.api.pushEvent(name, {
|
||||
url: res.config.url,
|
||||
url: res.config?.url,
|
||||
status: `${res.status}`,
|
||||
statusText: `${res.statusText}`,
|
||||
method: res.config.method.toUpperCase(),
|
||||
method: res.config?.method.toUpperCase(),
|
||||
});
|
||||
};
|
||||
|
||||
pushAxiosNetworkError = (res: AxiosResponse) => {
|
||||
this.faro?.api.pushError(new Error(`Network error: ${res.status}`), {
|
||||
context: {
|
||||
url: res.config.url,
|
||||
url: res.config?.url,
|
||||
type: 'network',
|
||||
data: `${safeJSONStringify(res.data)}`,
|
||||
status: `${res.status}`,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue