MM-62489 Fix error bar showing with developer mode disabled (#29911)

* MM-62489 Fix error bar showing with developer mode disabled

* Add changes that I forgot earlier
Этот коммит содержится в:
Harrison Healey
2025-01-23 15:34:08 -05:00
коммит произвёл GitHub
родитель 6f737ac5ee
Коммит 481c18c7cc
7 изменённых файлов: 85 добавлений и 22 удалений

Просмотреть файл

@@ -6,7 +6,7 @@ import {useIntl} from 'react-intl';
import {useSelector, useDispatch} from 'react-redux'; import {useSelector, useDispatch} from 'react-redux';
import {useLocation, useHistory} from 'react-router-dom'; import {useLocation, useHistory} from 'react-router-dom';
import {clearErrors, logError} from 'mattermost-redux/actions/errors'; import {clearErrors, logError, LogErrorBarMode} from 'mattermost-redux/actions/errors';
import {verifyUserEmail, getMe} from 'mattermost-redux/actions/users'; import {verifyUserEmail, getMe} from 'mattermost-redux/actions/users';
import {getIsOnboardingFlowEnabled} from 'mattermost-redux/selectors/entities/preferences'; import {getIsOnboardingFlowEnabled} from 'mattermost-redux/selectors/entities/preferences';
import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users'; import {getCurrentUserId} from 'mattermost-redux/selectors/entities/users';
@@ -91,7 +91,7 @@ const DoVerifyEmail = () => {
dispatch(logError({ dispatch(logError({
message: AnnouncementBarMessages.EMAIL_VERIFIED, message: AnnouncementBarMessages.EMAIL_VERIFIED,
type: AnnouncementBarTypes.SUCCESS, type: AnnouncementBarTypes.SUCCESS,
} as any, true)); } as any, {errorBarMode: LogErrorBarMode.Always}));
trackEvent('settings', 'verify_email'); trackEvent('settings', 'verify_email');

Просмотреть файл

@@ -11,6 +11,8 @@ import type {UserPropertyField} from '@mattermost/types/properties';
import type {UserProfile} from '@mattermost/types/users'; import type {UserProfile} from '@mattermost/types/users';
import type {IDMappedObjects} from '@mattermost/types/utilities'; import type {IDMappedObjects} from '@mattermost/types/utilities';
import type {LogErrorOptions} from 'mattermost-redux/actions/errors';
import {LogErrorBarMode} from 'mattermost-redux/actions/errors';
import {Client4} from 'mattermost-redux/client'; import {Client4} from 'mattermost-redux/client';
import type {ActionResult} from 'mattermost-redux/types/actions'; import type {ActionResult} from 'mattermost-redux/types/actions';
import {isEmail} from 'mattermost-redux/utils/helpers'; import {isEmail} from 'mattermost-redux/utils/helpers';
@@ -111,7 +113,7 @@ export type Props = {
maxFileSize: number; maxFileSize: number;
customProfileAttributeFields: IDMappedObjects<UserPropertyField>; customProfileAttributeFields: IDMappedObjects<UserPropertyField>;
actions: { actions: {
logError: ({message, type}: {message: any; type: string}, status: boolean) => void; logError: ({message, type}: {message: any; type: string}, options?: LogErrorOptions) => void;
clearErrors: () => void; clearErrors: () => void;
updateMe: (user: UserProfile) => Promise<ActionResult>; updateMe: (user: UserProfile) => Promise<ActionResult>;
sendVerificationEmail: (email: string) => Promise<ActionResult>; sendVerificationEmail: (email: string) => Promise<ActionResult>;
@@ -324,7 +326,7 @@ export class UserSettingsGeneralTab extends PureComponent<Props, State> {
this.props.actions.logError({ this.props.actions.logError({
message: AnnouncementBarMessages.EMAIL_VERIFICATION_REQUIRED, message: AnnouncementBarMessages.EMAIL_VERIFICATION_REQUIRED,
type: AnnouncementBarTypes.SUCCESS, type: AnnouncementBarTypes.SUCCESS,
}, true); }, {errorBarMode: LogErrorBarMode.Always});
} }
} else if (err) { } else if (err) {
let serverError; let serverError;

Просмотреть файл

@@ -4,7 +4,7 @@
import React from 'react'; import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import {logError} from 'mattermost-redux/actions/errors'; import {logError, LogErrorBarMode} from 'mattermost-redux/actions/errors';
import store from 'stores/redux_store'; import store from 'stores/redux_store';
@@ -42,8 +42,7 @@ function preRenderSetup(onPreRenderSetupReady: () => void) {
stack: error?.stack, stack: error?.stack,
url, url,
}, },
true, {errorBarMode: LogErrorBarMode.InDevMode},
true,
), ),
); );
}; };

Просмотреть файл

@@ -3,11 +3,11 @@
import nock from 'nock'; import nock from 'nock';
import {logError} from 'mattermost-redux/actions/errors'; import {logError, LogErrorBarMode, shouldShowErrorBar} from 'mattermost-redux/actions/errors';
import {Client4} from 'mattermost-redux/client'; import {Client4} from 'mattermost-redux/client';
import TestHelper from '../../test/test_helper'; import TestHelper from '../../test/test_helper';
import configureStore from '../../test/test_store'; import configureStore, {makeInitialState} from '../../test/test_store';
describe('Actions.Errors', () => { describe('Actions.Errors', () => {
let store = configureStore(); let store = configureStore();
@@ -60,3 +60,26 @@ describe('Actions.Errors', () => {
} }
}); });
}); });
test('shouldShowErrorBar', () => {
function makeTestState(enableDevMode: boolean) {
return makeInitialState({
entities: {
general: {
config: {
EnableDeveloper: enableDevMode.toString(),
},
},
},
});
}
expect(shouldShowErrorBar(makeTestState(false), {})).toBe(false);
expect(shouldShowErrorBar(makeTestState(true), {})).toBe(false);
expect(shouldShowErrorBar(makeTestState(false), {errorBarMode: LogErrorBarMode.Never})).toBe(false);
expect(shouldShowErrorBar(makeTestState(true), {errorBarMode: LogErrorBarMode.Never})).toBe(false);
expect(shouldShowErrorBar(makeTestState(false), {errorBarMode: LogErrorBarMode.Always})).toBe(true);
expect(shouldShowErrorBar(makeTestState(true), {errorBarMode: LogErrorBarMode.Always})).toBe(true);
expect(shouldShowErrorBar(makeTestState(false), {errorBarMode: LogErrorBarMode.InDevMode})).toBe(false);
expect(shouldShowErrorBar(makeTestState(true), {errorBarMode: LogErrorBarMode.InDevMode})).toBe(true);
});

Просмотреть файл

@@ -6,6 +6,7 @@ import type {ErrorObject} from 'serialize-error';
import {LogLevel} from '@mattermost/types/client4'; import {LogLevel} from '@mattermost/types/client4';
import type {ServerError} from '@mattermost/types/errors'; import type {ServerError} from '@mattermost/types/errors';
import type {GlobalState} from '@mattermost/types/store';
import {ErrorTypes} from 'mattermost-redux/action_types'; import {ErrorTypes} from 'mattermost-redux/action_types';
import {Client4} from 'mattermost-redux/client'; import {Client4} from 'mattermost-redux/client';
@@ -28,7 +29,36 @@ export function getLogErrorAction(error: ErrorObject, displayable = false) {
}; };
} }
export function logError(error: ServerError, displayable = false, consoleError = false): ActionFuncAsync<boolean> { export type LogErrorOptions = {
/**
* errorBarMode controls how and when the error bar is shown for this error.
*
* If unspecified, this defaults to DontShow.
*/
errorBarMode?: LogErrorBarMode;
};
export enum LogErrorBarMode {
/**
* Always show the error bar for this error.
*/
Always = 'Always',
/**
* Never show the error bar for this error.
*/
Never = 'Never',
/**
* Only shows the error bar if Developer Mode is enabled, and the message displayed will tell the user to check the
* JS console for more information.
*/
InDevMode = 'InDevMode',
}
export function logError(error: ServerError, options: LogErrorOptions = {}): ActionFuncAsync<boolean> {
return async (dispatch, getState) => { return async (dispatch, getState) => {
if (error.server_error_id === 'api.context.session_expired.app_error') { if (error.server_error_id === 'api.context.session_expired.app_error') {
return {data: true}; return {data: true};
@@ -55,24 +85,29 @@ export function logError(error: ServerError, displayable = false, consoleError =
} }
} }
if (consoleError) { if (options && options.errorBarMode === LogErrorBarMode.InDevMode) {
serializedError.message = 'A JavaScript error has occurred. Please use the JavaScript console to capture and report the error'; serializedError.message = 'A JavaScript error has occurred. Please use the JavaScript console to capture and report the error';
} }
const isDevMode = getState()?.entities.general?.config?.EnableDeveloper === 'true'; dispatch(getLogErrorAction(serializedError, shouldShowErrorBar(getState(), options)));
let shouldDisplay = displayable;
// Display announcements bar if error is a developer error and we are in dev mode
if (isDevMode && error.type === 'developer') {
shouldDisplay = true;
}
dispatch(getLogErrorAction(serializedError, shouldDisplay));
return {data: true}; return {data: true};
}; };
} }
export function shouldShowErrorBar(state: GlobalState, options: LogErrorOptions) {
if (options && options.errorBarMode === LogErrorBarMode.Always) {
return true;
}
if (options && options.errorBarMode === LogErrorBarMode.InDevMode) {
const isDevMode = state.entities.general.config?.EnableDeveloper === 'true';
return isDevMode;
}
return false;
}
export function clearErrors() { export function clearErrors() {
return { return {
type: ErrorTypes.CLEAR_ERRORS, type: ErrorTypes.CLEAR_ERRORS,

Просмотреть файл

@@ -37,7 +37,7 @@ import {getCurrentUserId, getUsersByUsername} from 'mattermost-redux/selectors/e
import type {ActionResult, DispatchFunc, GetStateFunc, ActionFunc, ActionFuncAsync, ThunkActionFunc} from 'mattermost-redux/types/actions'; import type {ActionResult, DispatchFunc, GetStateFunc, ActionFunc, ActionFuncAsync, ThunkActionFunc} from 'mattermost-redux/types/actions';
import {isCombinedUserActivityPost} from 'mattermost-redux/utils/post_list'; import {isCombinedUserActivityPost} from 'mattermost-redux/utils/post_list';
import {logError} from './errors'; import {logError, LogErrorBarMode} from './errors';
// receivedPost should be dispatched after a single post from the server. This typically happens when an existing post // receivedPost should be dispatched after a single post from the server. This typically happens when an existing post
// is updated. // is updated.
@@ -1325,7 +1325,7 @@ export function restorePostVersion(postId: string, restoreVersionId: string, con
} catch (error) { } catch (error) {
// Send to error bar if it's an edit post error about time limit. // Send to error bar if it's an edit post error about time limit.
if (error.server_error_id === 'api.post.update_post.permissions_time_limit.app_error') { if (error.server_error_id === 'api.post.update_post.permissions_time_limit.app_error') {
dispatch(logError({type: 'announcement', message: error.message}, true)); dispatch(logError({type: 'announcement', message: error.message}, {errorBarMode: LogErrorBarMode.Always}));
} else { } else {
dispatch(logError(error)); dispatch(logError(error));
} }

Просмотреть файл

@@ -3,6 +3,10 @@
import configureStore from 'mattermost-redux/store'; import configureStore from 'mattermost-redux/store';
export function makeInitialState(preloadedState) {
return testConfigureStore(preloadedState).getState();
}
export default function testConfigureStore(preloadedState) { export default function testConfigureStore(preloadedState) {
const store = configureStore({preloadedState, appReducers: {}, getAppReducers: () => {}}); const store = configureStore({preloadedState, appReducers: {}, getAppReducers: () => {}});