(core) When getting error details for on-demand formulas, provide an explanation

Summary:
Since formula errors are typically obtained from the Python data engine, they
were not returning any info for errors in on-demand tables (not loaded into the
data engine). This change implements a detailed message to explain such errors,
mainly to point out that on-demand table is the reason.

Test Plan: Added a check to the OnDemand test that formula error details are shown.

Reviewers: jarek

Reviewed By: jarek

Differential Revision: https://phab.getgrist.com/D4317
This commit is contained in:
Dmitry S 2024-08-13 09:48:54 -04:00
parent 95320f3f5b
commit 5ef54b278f
3 changed files with 26 additions and 1 deletions

View File

@ -480,6 +480,7 @@ function _isInIdentifier(line: string, column: number) {
/**
* Open a formula editor. Returns a Disposable that owns the editor.
* This is used for the editor in the side panel.
*/
export function openFormulaEditor(options: {
gristDoc: GristDoc,

View File

@ -138,7 +138,7 @@ import {
OptDocSession
} from './DocSession';
import {createAttachmentsIndex, DocStorage, REMOVE_UNUSED_ATTACHMENTS_DELAY} from './DocStorage';
import {expandQuery} from './ExpandedQuery';
import {expandQuery, getFormulaErrorForExpandQuery} from './ExpandedQuery';
import {GranularAccess, GranularAccessForBundle} from './GranularAccess';
import {OnDemandActions} from './OnDemandActions';
import {getLogMetaFromDocSession, getPubSubPrefix, getTelemetryMetaFromDocSession} from './serverUtils';
@ -1169,6 +1169,11 @@ export class ActiveDoc extends EventEmitter {
this._log.info(docSession, "getFormulaError(%s, %s, %s, %s)",
docSession, tableId, colId, rowId);
await this.waitForInitialization();
const onDemand = this._onDemandActions.isOnDemand(tableId);
if (onDemand) {
// It's safe to use this.docData after waitForInitialization().
return getFormulaErrorForExpandQuery(this.docData!, tableId, colId);
}
return this._pyCall('get_formula_error', tableId, colId, rowId);
}

View File

@ -1,5 +1,6 @@
import { ServerQuery } from 'app/common/ActiveDocAPI';
import { ApiError } from 'app/common/ApiError';
import { CellValue } from 'app/common/DocActions';
import { DocData } from 'app/common/DocData';
import { parseFormula } from 'app/common/Formula';
import { removePrefix } from 'app/common/gutil';
@ -133,6 +134,24 @@ export function expandQuery(iquery: ServerQuery, docData: DocData, onDemandFormu
return query;
}
export function getFormulaErrorForExpandQuery(docData: DocData, tableId: string, colId: string): CellValue {
// On-demand tables may produce several kinds of error messages, e.g. "Formula not supported" or
// "Cannot find column". We construct the full query to get the basic message for the requested
// column, then tack on the detail, which is fine to be the same for all of them.
const iquery: ServerQuery = {tableId, filters: {}};
const expanded = expandQuery(iquery, docData, true);
const constantValue = expanded.constants?.[colId];
if (constantValue?.length === 2) {
return [GristObjCode.Exception, constantValue[1],
`Not supported in on-demand tables.
This table is marked as an on-demand table. Such tables don't support most formulas. \
For proper formula support, unmark it as on-demand.
`];
}
return null;
}
/**
* Build a query that relates two homogeneous tables sharing a common set of columns,
* returning rows that exist in both tables (if they have differences), and rows from