Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
fix: add intl message for action type codes (#622)
Browse files Browse the repository at this point in the history
Now instead of saying "RUN_EXTRACTOR_ASYNC" Failed it should say "Running extractor Failed"

Kind of hack on top of react-intl file which re-uses ActionType codes.

Longer term solution needs a lot of work in re-architecting how to we send error messages. Instead of putting explicit setErrorDisplay it would be better to overload the global error handler and let this be handled by default.
  • Loading branch information
mattmazzola authored Jun 25, 2018
1 parent 769c9b8 commit f717ddb
Show file tree
Hide file tree
Showing 11 changed files with 65 additions and 31 deletions.
3 changes: 1 addition & 2 deletions src/ErrorHandler.tsx → src/ErrorHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ export interface ErrorCallback {
}

export class ErrorHandler {

static callbacks: ErrorCallback[] = [];
private static callbacks: ErrorCallback[] = [];

public static registerCallbacks(callbacks: ErrorCallback[]): string {
let guid = generateGUID();
Expand Down
8 changes: 0 additions & 8 deletions src/ErrorInjector.tsx → src/ErrorInjector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@
*/
import { AT } from './types/ActionTypes'

export interface ErrorCallback {
actionType: AT;
callback: ((actionType: AT) => void);
guid?: string;
}

export class ErrorInjector {

private static disabledActions: string[] = [];

public static SetError(actionType: string, enabled: boolean) {
Expand All @@ -26,5 +19,4 @@ export class ErrorInjector {
public static ShouldError(actionType: AT) {
return (ErrorInjector.disabledActions.find(s => s == AT[AT[actionType]]) != null)
}

}
6 changes: 3 additions & 3 deletions src/actions/displayActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ export const setErrorDisplay = (errorType: ErrorType, title: string, messages: s
return {
type: AT.SET_ERROR_DISPLAY,
errorType,
title: title,
messages: messages,
actionType: actionType
title,
messages,
actionType
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/components/modals/AppCreator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ class AppCreator extends React.Component<Props, ComponentState> {
const appInput = this.getAppInput();
this.props.onSubmit(appInput, source)
}
catch (error) {
catch (e) {
const error = e as Error
this.props.setErrorDisplay(ErrorType.Error, error.message, ["Invalid file contents"], AT.CREATE_APPLICATION_ASYNC)
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/components/modals/ErrorPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { Panel, PanelType, FontClassNames, DefaultButton } from 'office-ui-fabri
import { clearErrorDisplay } from '../../actions/displayActions'
import { State } from '../../types'
import { ErrorHandler } from '../../ErrorHandler'
import { injectIntl, InjectedIntlProps, InjectedIntl } from 'react-intl'
import { injectIntl, InjectedIntlProps, InjectedIntl, FormattedMessage } from 'react-intl'
import { AT } from '../../types/ActionTypes'
import { FM } from '../../react-intl-messages'
import { GetTip, TipType } from '../ToolTips'
Expand Down Expand Up @@ -88,7 +88,11 @@ class ErrorPanel extends React.Component<Props, {}> {
customWidth='600px'
>
<div className="cl-errorpanel" >
{this.props.error.actionType && <div className={FontClassNames.large}>{this.props.error.actionType} Failed</div>}
{this.props.error.actionType && <div className={FontClassNames.large}>
<FormattedMessage
id={this.props.error.actionType || FM.ERROR_ERROR}
defaultMessage='Unknown '
/> Failed</div>}
<div className={FontClassNames.medium}>{this.props.error.error}</div>
{this.props.error && this.props.error.messages.map((message: any) => {
if (message == null)
Expand Down
38 changes: 36 additions & 2 deletions src/react-intl-messages.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AT } from "./types";

/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
Expand Down Expand Up @@ -488,8 +490,6 @@ export default {
[FM.BUTTON_IMPORT]: 'Import',
[FM.BUTTON_INFO]: 'Info',

// Custom Errors
[FM.CUSTOMERROR_NETWORK_ERROR]: 'Is your Bot running?',

// Dashboard
[FM.DASHBOARD_TITLE]: 'Overview',
Expand Down Expand Up @@ -849,6 +849,40 @@ export default {
[FM.TRAINDIALOGMODAL_PRIMARYBUTTON_ARIADESCRIPTION]: 'Done',
[FM.TRAINDIALOGMODAL_PRIMARYBUTTON_TEXT]: 'Done',
[FM.TRAINDIALOGMODAL_CONFIRMDELETE_TITLE]: 'Are you sure you want to delete this Training Dialog?',

// Error Messages
[FM.CUSTOMERROR_NETWORK_ERROR]: 'Is your Bot running?',
/**
* This is kind of hack which re-uses redux action types as unit strings for localized error messages
*
* It should probably be `errors.application.create` but we're using something like: `CREATE_APPLICATION_ASYNC`
*/
[AT.CREATE_APPLICATION_ASYNC]: 'Creating application',
[AT.COPY_APPLICATION_ASYNC]: 'Copying application ',
[AT.CREATE_ENTITY_ASYNC]: 'Creating entity',
[AT.CREATE_ACTION_ASYNC]: 'Creating action',
[AT.CREATE_APP_TAG_ASYNC]: 'Creating application tag',
[AT.CREATE_CHAT_SESSION_ASYNC]: 'Creating chat session',
[AT.CREATE_TEACH_SESSION_ASYNC]: 'Creating teach session',
[AT.CREATE_TEACH_SESSION_FROMHISTORYASYNC]: 'Creating teach session from history',
[AT.CREATE_TEACH_SESSION_FROMUNDOASYNC]: 'Creating teach session from undo',
[AT.FETCH_HISTORY_ASYNC]: 'Fetching history',
[AT.FETCH_TUTORIALS_ASYNC]: 'Fetching tutorials',
[AT.FETCH_APPSOURCE_ASYNC]: 'Fetching application source',
[AT.FETCH_ENTITY_DELETE_VALIDATION_ASYNC]: 'Fetching entity deletion information',
[AT.FETCH_ENTITY_EDIT_VALIDATION_ASYNC]: 'Fetching entity edit information',
[AT.FETCH_ACTION_DELETE_VALIDATION_ASYNC]: 'Fetching action delete information',
[AT.FETCH_ACTION_EDIT_VALIDATION_ASYNC]: 'Fetching action edit information',
[AT.INIT_MEMORY_ASYNC]: 'Initializing memory',
[AT.RUN_EXTRACTOR_ASYNC]: 'Running extractor',
[AT.GET_SCORES_ASYNC]: 'Fetching scores',
[AT.RUN_SCORER_ASYNC]: 'Running scorer',
[AT.POST_SCORE_FEEDBACK_ASYNC]: 'Fetching score feedback',
[AT.EDIT_ENTITY_ASYNC]: 'Editing entity',
[AT.EDIT_ACTION_ASYNC]: 'Editing action',
[AT.EDIT_TRAINDIALOG_ASYNC]: 'Editing train dialog',
[AT.EDIT_APP_LIVE_TAG_ASYNC]: 'Editing application live tag',
[AT.EDIT_APP_EDITING_TAG_ASYNC]: 'Editing application editing tag',
},
'ko': {
[FM.ABOUT_TITLE]: '약',
Expand Down
18 changes: 14 additions & 4 deletions src/reducers/errorReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,27 @@ const initialState: ErrorState = {
error: null,
messages: null,
actionType: AT.NO_OP
};
}

const errorReducer: Reducer<ErrorState> = (state = initialState, action: ActionObject): ErrorState => {
switch (action.type) {
case AT.CLEAR_ERROR_DISPLAY:
return { ...initialState };
return { ...initialState }
case AT.SET_ERROR_DISPLAY:
return { errorType: action.errorType, error: action.title, messages: action.messages, actionType: action.actionType }
return {
errorType: action.errorType,
error: action.title,
messages: action.messages,
actionType: action.actionType
}
case AT.FETCH_BOTINFO_FULFILLED:
if (action.botInfo.validationErrors.length > 0) {
return { errorType: ErrorType.Error, error: `Configuration Error`, messages: action.botInfo.validationErrors, actionType: null }
return {
errorType: ErrorType.Error,
error: `Configuration Error`,
messages: action.botInfo.validationErrors,
actionType: null
}
}
return { ...state }
default:
Expand Down
2 changes: 0 additions & 2 deletions src/routes/Apps/App/Index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import { AppBase, AppDefinition, ActionBase, ActionTypes, ApiAction, CardAction,
import { injectIntl, InjectedIntlProps } from 'react-intl'
import { FM } from '../../../react-intl-messages'
import { State } from '../../../types';
import { setErrorDisplay } from '../../../actions/displayActions';
import { Icon } from 'office-ui-fabric-react/lib/Icon'
import Entities from './Entities'
import TrainDialogs from './TrainDialogs'
Expand Down Expand Up @@ -245,7 +244,6 @@ class Index extends React.Component<Props, ComponentState> {
}
const mapDispatchToProps = (dispatch: any) => {
return bindActionCreators({
setErrorDisplay,
setCurrentApp: actions.display.setCurrentApp,
createApplicationThunkAsync: actions.create.createApplicationThunkAsync,
fetchAppSource: actions.fetch.fetchAppSourceThunkAsync,
Expand Down
4 changes: 1 addition & 3 deletions src/routes/Apps/App/LogDialogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
} from '../../../actions/createActions'
import { deleteLogDialogThunkAsync } from '../../../actions/deleteActions';
import { fetchAllLogDialogsAsync, fetchHistoryThunkAsync } from '../../../actions/fetchActions';
import { setErrorDisplay } from '../../../actions/displayActions';
import { injectIntl, InjectedIntl, InjectedIntlProps, FormattedMessage } from 'react-intl'
import { FM } from '../../../react-intl-messages'
import { Activity } from 'botframework-directlinejs';
Expand Down Expand Up @@ -599,7 +598,7 @@ class LogDialogs extends React.Component<Props, ComponentState> {
teach={this.props.teachSessions.current}
dialogMode={this.props.teachSessions.mode}
isOpen={this.state.isTeachDialogModalOpen}
onClose={this.onCloseTeachSession}
onClose={this.onCloseTeachSession}
onUndo={(popRound) => this.onUndoTeachStep(popRound)}
history={this.state.isTeachDialogModalOpen ? this.state.history : null}
lastAction={this.state.lastAction}
Expand All @@ -618,7 +617,6 @@ const mapDispatchToProps = (dispatch: any) => {
deleteLogDialogThunkAsync,
fetchAllLogDialogsAsync,
fetchHistoryThunkAsync,
setErrorDisplay
}, dispatch)
}
const mapStateToProps = (state: State) => {
Expand Down
2 changes: 0 additions & 2 deletions src/routes/Apps/App/TrainDialogs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import { deleteTrainDialogThunkAsync, deleteMemoryThunkAsync } from '../../../ac
import { editTrainDialogThunkAsync } from '../../../actions/updateActions';
import { injectIntl, InjectedIntl, InjectedIntlProps, FormattedMessage } from 'react-intl'
import { FM } from '../../../react-intl-messages'
import { setErrorDisplay } from '../../../actions/displayActions';
import { Activity } from 'botframework-directlinejs';
import { autobind } from 'office-ui-fabric-react/lib/Utilities';
import { getDefaultEntityMap } from '../../../util';
Expand Down Expand Up @@ -750,7 +749,6 @@ const mapDispatchToProps = (dispatch: any) => {
createTeachSessionFromUndoThunkAsync,
createTeachSessionFromHistoryThunkAsync,
editTrainDialogThunkAsync,
setErrorDisplay
}, dispatch)
}
const mapStateToProps = (state: State) => {
Expand Down
4 changes: 2 additions & 2 deletions src/services/poller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe('Poller', () => {
await poller1.addPoll(pollConfig)

expect(onExpiredMock.mock.calls.length).toBe(1)
expect(onUpdateMock.mock.calls.length).toBeGreaterThan(3)
expect(onUpdateMock.mock.calls.length).toBeGreaterThanOrEqual(3)
})

test('poll should invoke request, isResolved, and onUpdate for each interval', async () => {
Expand Down Expand Up @@ -143,6 +143,6 @@ describe('Poller', () => {
await p1 // Will still resolve after 400 expiration
const after = new Date().getTime()

expect(after - now).toBeGreaterThan(400)
expect(after - now).toBeGreaterThanOrEqual(400)
})
})

0 comments on commit f717ddb

Please sign in to comment.