Skip to content

Commit 3e48300

Browse files
committed
Add the data transfer skipping when the transformation script returns undefined.
1 parent f1c1e92 commit 3e48300

6 files changed

Lines changed: 113 additions & 152 deletions

File tree

src/framework/components/PageComposition/ErrorBoundary.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
22

3+
const style = {color: 'white', backgroundColor: 'red', borderRadius: '4px', padding: '.5em', overflow: 'auto'};
4+
35
class ErrorBoundary extends React.Component {
46
constructor (props) {
57
super(props);
@@ -15,12 +17,14 @@ class ErrorBoundary extends React.Component {
1517
if (hasError) {
1618
const { pageName } = this.props;
1719
return (
18-
<div style={{color: 'white', backgroundColor: 'red', borderRadius: '4px', padding: '.5em'}}>
20+
<div style={style}>
1921
<code>Error occurred in "{pageName}" page: </code>
20-
<code>{error && error.message}</code>
22+
<pre><code>{error && error.message}</code></pre>
2123
</div>
2224
);
2325
}
2426
return this.props.children;
2527
}
2628
}
29+
30+
export default ErrorBoundary;

src/framework/components/PageComposition/PageComposition.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import isArray from 'lodash/isArray';
88
import isPlainObject from 'lodash/isObject';
99
import React, { Component } from 'react';
1010
import PropTypes from 'prop-types';
11+
import ErrorBoundary from './ErrorBoundary';
1112
import NotFoundComponent from '../NotFoundComponent';
1213
import createContainer from './Container';
1314
import WarningComponent from '../WarningComponent';
@@ -214,7 +215,11 @@ class PageComposition extends Component {
214215
}
215216

216217
render () {
217-
return this.renderPage();
218+
return (
219+
<ErrorBoundary pageName={this.props.routePath}>
220+
{this.renderPage()}
221+
</ErrorBoundary>
222+
);
218223
}
219224
}
220225

src/framework/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { createBrowserHistory } from 'history';
44
import { configureStore } from './store/store';
55
import { clearActionsCache } from './store/actions';
66
import { createActionSequences } from './store/sequences';
7-
import { resetStoreItems } from './store/functions';
87

98
import PageRouter from './components/PageRouter';
109
import StartWrapper from './components/StartWrapper';
@@ -101,7 +100,6 @@ class Application extends React.Component {
101100
)
102101
}
103102
}
104-
resetStoreItems();
105103
clearActionsCache();
106104
const { routes, pages, flows } = schema;
107105
const { actionSequences, targetProperties } = createActionSequences(flows, userFunctions);

src/framework/store/actions.js

Lines changed: 100 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import isUndefined from 'lodash/isUndefined';
88
import { COMPONENT_TYPE, USER_FUNCTION_TYPE, DISPATCH_ERROR_TYPE} from './constants';
99
import { getUserFunctionByName } from './sequences';
1010

11+
const TRANSFORMATION_ERROR_SKIP_DATA_TRANSFERRING = 'TRANSFORMATION_ERROR_SKIP_DATA_TRANSFERRING';
12+
1113
let sendDebugMessage;
1214
let constants;
1315
if (process.env.NODE_ENV !== 'production') {
@@ -36,8 +38,10 @@ function transformFirstArgument (elementKey, transformScript, firstArgument) {
3638
try {
3739
firstArgumentResult = transformFunction(firstArgument);
3840
} catch (error) {
39-
console.error(`[Framework] Transformation function error: ${error.message}`);
40-
firstArgumentResult = firstArgument;
41+
throw Error(`Transformation function error: ${error.message}`);
42+
}
43+
if (typeof firstArgumentResult === 'undefined') {
44+
throw Error(TRANSFORMATION_ERROR_SKIP_DATA_TRANSFERRING);
4145
}
4246
} else {
4347
firstArgumentResult = firstArgument;
@@ -50,40 +54,56 @@ function dispatchToComponent (taskEventName, props, payload, dispatch, helpers)
5054
const {
5155
componentName, componentInstance, propertyName, forwardPath, componentKey, transformScript
5256
} = props;
53-
const transformedPayload = transformFirstArgument(componentKey, transformScript, payload);
54-
if (forwardPath && helpers) {
55-
const { history } = helpers;
56-
if (history) {
57-
// hmmm... why there can not be the history helper?
58-
let pathString = `/${forwardPath}`;
59-
if (!isUndefined(transformedPayload)) {
60-
if (isNumber(transformedPayload) || isString(transformedPayload)) {
61-
// if user function dispatches string or number we pass it as the :parameter in the http request
62-
pathString = `${pathString}/${transformedPayload}`;
63-
} else if (isObject(transformedPayload) || isArray(transformedPayload)) {
64-
// if user function dispatches an object or an array we pass it as the request query
65-
pathString = `${pathString}?${queryString.stringify(transformedPayload)}`;
66-
} else {
67-
console.error(
68-
'[Framework] The mapping to parameters in URL is possible only for ' +
69-
'a string, a number, an object, or an array.'
70-
);
57+
try {
58+
const transformedPayload = transformFirstArgument(componentKey, transformScript, payload);
59+
if (forwardPath && helpers) {
60+
const { history } = helpers;
61+
if (history) {
62+
// hmmm... why there can not be the history helper?
63+
let pathString = `/${forwardPath}`;
64+
if (!isUndefined(transformedPayload)) {
65+
if (isNumber(transformedPayload) || isString(transformedPayload)) {
66+
// if user function dispatches string or number we pass it as the :parameter in the http request
67+
pathString = `${pathString}/${transformedPayload}`;
68+
} else if (isObject(transformedPayload) || isArray(transformedPayload)) {
69+
// if user function dispatches an object or an array we pass it as the request query
70+
pathString = `${pathString}?${queryString.stringify(transformedPayload)}`;
71+
} else {
72+
console.error(
73+
'[Framework] The mapping to parameters in URL is possible only for ' +
74+
'a string, a number, an object, or an array.'
75+
);
76+
}
7177
}
78+
if (process.env.NODE_ENV !== 'production') {
79+
sendDebugMessage({
80+
key: componentKey,
81+
eventType: constants.DEBUG_MSG_FORWARD_EVENT,
82+
forwardPath,
83+
inputData: transformedPayload,
84+
propertyName,
85+
pathString,
86+
timestamp: Date.now(),
87+
});
88+
}
89+
history.push(pathString);
90+
} else if (propertyName) {
91+
// hmmm... why there can not be the history helper?
92+
const targetKey = `${componentName}_${componentInstance}`;
93+
if (process.env.NODE_ENV !== 'production') {
94+
sendDebugMessage({
95+
key: componentKey,
96+
eventType: constants.DEBUG_MSG_REDUCE_DATA_EVENT,
97+
inputData: transformedPayload,
98+
componentName,
99+
componentInstance,
100+
propertyName,
101+
timestamp: Date.now(),
102+
});
103+
}
104+
dispatch({ type: targetKey, payload: { [propertyName]: transformedPayload } });
72105
}
73-
if (process.env.NODE_ENV !== 'production') {
74-
sendDebugMessage({
75-
key: componentKey,
76-
eventType: constants.DEBUG_MSG_FORWARD_EVENT,
77-
forwardPath,
78-
inputData: transformedPayload,
79-
propertyName,
80-
pathString,
81-
timestamp: Date.now(),
82-
});
83-
}
84-
history.push(pathString);
85-
} else if (propertyName) {
86-
// hmmm... why there can not be the history helper?
106+
} else {
87107
const targetKey = `${componentName}_${componentInstance}`;
88108
if (process.env.NODE_ENV !== 'production') {
89109
sendDebugMessage({
@@ -98,20 +118,10 @@ function dispatchToComponent (taskEventName, props, payload, dispatch, helpers)
98118
}
99119
dispatch({ type: targetKey, payload: { [propertyName]: transformedPayload } });
100120
}
101-
} else {
102-
const targetKey = `${componentName}_${componentInstance}`;
103-
if (process.env.NODE_ENV !== 'production') {
104-
sendDebugMessage({
105-
key: componentKey,
106-
eventType: constants.DEBUG_MSG_REDUCE_DATA_EVENT,
107-
inputData: transformedPayload,
108-
componentName,
109-
componentInstance,
110-
propertyName,
111-
timestamp: Date.now(),
112-
});
121+
} catch (e) {
122+
if (e && e.message !== TRANSFORMATION_ERROR_SKIP_DATA_TRANSFERRING) {
123+
console.error(`[Framework] ${e.message}`);
113124
}
114-
dispatch({ type: targetKey, payload: { [propertyName]: transformedPayload } });
115125
}
116126
}
117127
}
@@ -212,47 +222,53 @@ function createTasks (targets, taskEventName) {
212222
const args = arguments;
213223
return (dispatch, getState, helpers) => {
214224
// before execute the function we have to transform the input argument if needed
215-
const firstArgument =
216-
transformFirstArgument(props.functionKey, props.transformScript, args[0]);
217-
// execute user function with passed in args
218-
if (process.env.NODE_ENV !== 'production') {
219-
sendDebugMessage({
220-
key: props.functionKey,
221-
eventType: constants.DEBUG_MSG_FUNCTION_CALL_EVENT,
222-
inputData: firstArgument,
223-
functionName: props.functionName,
224-
timestamp: Date.now(),
225-
});
226-
}
227-
// the secondary argument is used in the store items function
228-
// to determine if we are reading from the store item or writing to it
229-
const userFunctionInstance = func.apply(null, [firstArgument]);
230225
try {
231-
// dispatch caughtException as null to the assigned targets
232-
caughtExceptionFunction(null, dispatch, getState, helpers);
233-
// now execute dispatching of the events objects to the targets
234-
const userFunctionResult = userFunctionInstance((dispatchType, payload) => {
235-
// user function is invoked now
236-
if (process.env.NODE_ENV !== 'production') {
237-
sendDebugMessage({
238-
key: props.functionKey,
239-
eventType: constants.DEBUG_MSG_FUNCTION_FIRE_EVENT,
240-
eventName: dispatchType,
241-
outputData: payload,
242-
functionName: props.functionName,
243-
timestamp: Date.now(),
226+
const firstArgument =
227+
transformFirstArgument(props.functionKey, props.transformScript, args[0]);
228+
// execute user function with passed in args
229+
if (process.env.NODE_ENV !== 'production') {
230+
sendDebugMessage({
231+
key: props.functionKey,
232+
eventType: constants.DEBUG_MSG_FUNCTION_CALL_EVENT,
233+
inputData: firstArgument,
234+
functionName: props.functionName,
235+
timestamp: Date.now(),
236+
});
237+
}
238+
// the secondary argument is used in the store items function
239+
// to determine if we are reading from the store item or writing to it
240+
const userFunctionInstance = func.apply(null, [firstArgument]);
241+
try {
242+
// dispatch caughtException as null to the assigned targets
243+
caughtExceptionFunction(null, dispatch, getState, helpers);
244+
// now execute dispatching of the events objects to the targets
245+
const userFunctionResult = userFunctionInstance((dispatchType, payload) => {
246+
// user function is invoked now
247+
if (process.env.NODE_ENV !== 'production') {
248+
sendDebugMessage({
249+
key: props.functionKey,
250+
eventType: constants.DEBUG_MSG_FUNCTION_FIRE_EVENT,
251+
eventName: dispatchType,
252+
outputData: payload,
253+
functionName: props.functionName,
254+
timestamp: Date.now(),
255+
});
256+
}
257+
dispatchFunction(dispatchType, payload, dispatch, getState, helpers);
258+
});
259+
// here user returns a Promise and there may be the error
260+
if (userFunctionResult && userFunctionResult.then) {
261+
userFunctionResult.catch(error => {
262+
caughtExceptionFunction(error, dispatch, getState, helpers);
244263
});
245264
}
246-
dispatchFunction(dispatchType, payload, dispatch, getState, helpers);
247-
});
248-
// here user returns a Promise and there may be the error
249-
if (userFunctionResult && userFunctionResult.then) {
250-
userFunctionResult.catch(error => {
251-
caughtExceptionFunction(error, dispatch, getState, helpers);
252-
});
265+
} catch (error) {
266+
caughtExceptionFunction(error, dispatch, getState, helpers);
267+
}
268+
} catch (e) {
269+
if (e && e.message !== TRANSFORMATION_ERROR_SKIP_DATA_TRANSFERRING) {
270+
console.error(`[Framework] ${e.message}`);
253271
}
254-
} catch (error) {
255-
caughtExceptionFunction(error, dispatch, getState, helpers);
256272
}
257273
};
258274
}

src/framework/store/functions.js

Lines changed: 0 additions & 61 deletions
This file was deleted.

src/framework/store/sequences.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import isObject from 'lodash/isObject';
77
import isEmpty from 'lodash/isEmpty';
88
import unionWith from 'lodash/unionWith';
99
import { COMPONENT_TYPE, USER_FUNCTION_TYPE } from './constants';
10-
import frameworkFunctions from './functions';
1110

1211
let userFunctions = {};
1312

@@ -214,7 +213,7 @@ function createActionSequencesRecursively (handlers, actionSequences = {}) {
214213
}
215214

216215
export function createActionSequences (handlers, functions) {
217-
userFunctions = {...functions, ...frameworkFunctions};
216+
userFunctions = {...functions};
218217
const actionSequences = createActionSequencesRecursively(handlers);
219218
const targetProperties = deriveTargetProperties(actionSequences);
220219
return { actionSequences, targetProperties };

0 commit comments

Comments
 (0)