diff --git a/packages/datalib/src/runMacro.ts b/packages/datalib/src/runMacro.ts
index 537d0863f..a5b266dda 100644
--- a/packages/datalib/src/runMacro.ts
+++ b/packages/datalib/src/runMacro.ts
@@ -25,9 +25,16 @@ export function runMacro(
macroArgs: {},
data: FreeTableModel,
preview: boolean,
- selectedCells: MacroSelectedCell[]
+ selectedCells: MacroSelectedCell[],
+ errors: string[] = []
): FreeTableModel {
- const func = eval(getMacroFunction[macro.type](macro.code));
+ let func;
+ try {
+ func = eval(getMacroFunction[macro.type](macro.code));
+ } catch (err) {
+ errors.push(`Error compiling macro ${macro.name}: ${err.message}`);
+ return data;
+ }
if (macro.type == 'transformValue') {
const selectedRows = _.groupBy(selectedCells, 'row');
const rows = data.rows.map((row, rowIndex) => {
@@ -38,7 +45,12 @@ export function runMacro(
for (const cell of selectedRow) {
const { column } = cell;
const oldValue = row[column];
- const newValue = func(oldValue, macroArgs, modules, rowIndex, row, column);
+ let newValue = oldValue;
+ try {
+ newValue = func(oldValue, macroArgs, modules, rowIndex, row, column);
+ } catch (err) {
+ errors.push(`Error processing column ${column} on row ${rowIndex}: ${err.message}`);
+ }
if (newValue != oldValue) {
if (res == null) {
res = { ...row };
diff --git a/packages/web/src/datagrid/DataGridCore.js b/packages/web/src/datagrid/DataGridCore.js
index d435d5d7b..449b15c5f 100644
--- a/packages/web/src/datagrid/DataGridCore.js
+++ b/packages/web/src/datagrid/DataGridCore.js
@@ -298,6 +298,16 @@ export default function DataGridCore(props) {
return ;
}
+ if (grider.errors && grider.errors.length > 0) {
+ return (
+
+ {grider.errors.map((err, index) => (
+
+ ))}
+
+ );
+ }
+
const handleRowScroll = (value) => {
setFirstVisibleRowScrollIndex(value);
};
diff --git a/packages/web/src/datagrid/Grider.ts b/packages/web/src/datagrid/Grider.ts
index bb8165c7e..0f24aeea4 100644
--- a/packages/web/src/datagrid/Grider.ts
+++ b/packages/web/src/datagrid/Grider.ts
@@ -50,6 +50,9 @@ export default abstract class Grider {
get disableLoadNextPage() {
return false;
}
+ get errors() {
+ return null;
+ }
updateRow(index, changeObject) {
for (const key of Object.keys(changeObject)) {
this.setCellValue(index, key, changeObject[key]);
diff --git a/packages/web/src/freetable/MacroPreviewGrider.ts b/packages/web/src/freetable/MacroPreviewGrider.ts
index 0a3682072..1c3081715 100644
--- a/packages/web/src/freetable/MacroPreviewGrider.ts
+++ b/packages/web/src/freetable/MacroPreviewGrider.ts
@@ -3,9 +3,14 @@ import Grider, { GriderRowStatus } from '../datagrid/Grider';
export default class MacroPreviewGrider extends Grider {
model: FreeTableModel;
+ _errors: string[] = [];
constructor(model: FreeTableModel, macro: MacroDefinition, macroArgs: {}, selectedCells: MacroSelectedCell[]) {
super();
- this.model = runMacro(macro, macroArgs, model, true, selectedCells);
+ this.model = runMacro(macro, macroArgs, model, true, selectedCells, this._errors);
+ }
+
+ get errors() {
+ return this._errors;
}
getRowStatus(index): GriderRowStatus {
diff --git a/packages/web/src/widgets/ErrorInfo.js b/packages/web/src/widgets/ErrorInfo.js
index 04e50d8ee..03905effc 100644
--- a/packages/web/src/widgets/ErrorInfo.js
+++ b/packages/web/src/widgets/ErrorInfo.js
@@ -14,7 +14,20 @@ const Icon = styled.div`
margin: 10px;
`;
-export default function ErrorInfo({ message, icon = 'fas fa-times-circle red' }) {
+const ContainerSmall = styled.div`
+ display: flex;
+ margin-right: 10px;
+`;
+
+export default function ErrorInfo({ message, icon = 'fas fa-times-circle red', isSmall = false }) {
+ if (isSmall) {
+ return (
+
+
+ {message}
+
+ );
+ }
return (