diff --git a/packages/builder/src/components/backend/DataTable/DataTable.svelte b/packages/builder/src/components/backend/DataTable/DataTable.svelte index 1f461ebad3..37742626cd 100644 --- a/packages/builder/src/components/backend/DataTable/DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/DataTable.svelte @@ -14,7 +14,13 @@ import Table from "./Table.svelte" import { TableNames } from "constants" import CreateEditRow from "./modals/CreateEditRow.svelte" - import { Pagination, Heading, Body, Layout } from "@budibase/bbui" + import { + Pagination, + Heading, + Body, + Layout, + notifications, + } from "@budibase/bbui" import { fetchData } from "@budibase/frontend-core" import { API } from "api" @@ -29,6 +35,13 @@ $: fetch = createFetch(id) $: hasCols = checkHasCols(schema) $: hasRows = !!$fetch.rows?.length + $: showError($fetch.error) + + const showError = error => { + if (error) { + notifications.error(error?.message || "Unable to fetch data.") + } + } const enrichSchema = schema => { let tempSchema = { ...schema } diff --git a/packages/frontend-core/src/fetch/DataFetch.js b/packages/frontend-core/src/fetch/DataFetch.js index ecd5313af5..338e6e0405 100644 --- a/packages/frontend-core/src/fetch/DataFetch.js +++ b/packages/frontend-core/src/fetch/DataFetch.js @@ -170,6 +170,7 @@ export default class DataFetch { rows: page.rows, info: page.info, cursors: paginate && page.hasNextPage ? [null, page.cursor] : [null], + error: page.error, })) } @@ -182,7 +183,7 @@ export default class DataFetch { const features = get(this.featureStore) // Get the actual data - let { rows, info, hasNextPage, cursor } = await this.getData() + let { rows, info, hasNextPage, cursor, error } = await this.getData() // If we don't support searching, do a client search if (!features.supportsSearch) { @@ -204,6 +205,7 @@ export default class DataFetch { info, hasNextPage, cursor, + error, } } @@ -345,8 +347,14 @@ export default class DataFetch { return } this.store.update($store => ({ ...$store, loading: true })) - const { rows, info } = await this.getPage() - this.store.update($store => ({ ...$store, rows, info, loading: false })) + const { rows, info, error } = await this.getPage() + this.store.update($store => ({ + ...$store, + rows, + info, + loading: false, + error, + })) } /** @@ -386,7 +394,7 @@ export default class DataFetch { cursor: nextCursor, pageNumber: $store.pageNumber + 1, })) - const { rows, info, hasNextPage, cursor } = await this.getPage() + const { rows, info, hasNextPage, cursor, error } = await this.getPage() // Update state this.store.update($store => { @@ -400,6 +408,7 @@ export default class DataFetch { info, cursors, loading: false, + error, } }) } @@ -421,7 +430,7 @@ export default class DataFetch { cursor: prevCursor, pageNumber: $store.pageNumber - 1, })) - const { rows, info } = await this.getPage() + const { rows, info, error } = await this.getPage() // Update state this.store.update($store => { @@ -430,6 +439,7 @@ export default class DataFetch { rows, info, loading: false, + error, } }) } diff --git a/packages/frontend-core/src/fetch/TableFetch.js b/packages/frontend-core/src/fetch/TableFetch.js index cf0e124020..a13b1bd186 100644 --- a/packages/frontend-core/src/fetch/TableFetch.js +++ b/packages/frontend-core/src/fetch/TableFetch.js @@ -37,6 +37,7 @@ export default class TableFetch extends DataFetch { return { rows: [], hasNextPage: false, + error, } } } diff --git a/packages/server/src/api/controllers/row/external.js b/packages/server/src/api/controllers/row/external.js index b1c322b8b6..c9f6aa2f78 100644 --- a/packages/server/src/api/controllers/row/external.js +++ b/packages/server/src/api/controllers/row/external.js @@ -128,25 +128,35 @@ exports.search = async ctx => { [params.sort]: direction, } } - const rows = await handleRequest(DataSourceOperation.READ, tableId, { - filters: query, - sort, - paginate: paginateObj, - }) - let hasNextPage = false - if (paginate && rows.length === limit) { - const nextRows = await handleRequest(DataSourceOperation.READ, tableId, { + try { + const rows = await handleRequest(DataSourceOperation.READ, tableId, { filters: query, sort, - paginate: { - limit: 1, - page: bookmark * limit + 1, - }, + paginate: paginateObj, }) - hasNextPage = nextRows.length > 0 + let hasNextPage = false + if (paginate && rows.length === limit) { + const nextRows = await handleRequest(DataSourceOperation.READ, tableId, { + filters: query, + sort, + paginate: { + limit: 1, + page: bookmark * limit + 1, + }, + }) + hasNextPage = nextRows.length > 0 + } + // need wrapper object for bookmarks etc when paginating + return { rows, hasNextPage, bookmark: bookmark + 1 } + } catch (err) { + if (err.message && err.message.includes("does not exist")) { + throw new Error( + `Table updated externally, please re-fetch - ${err.message}` + ) + } else { + throw err + } } - // need wrapper object for bookmarks etc when paginating - return { rows, hasNextPage, bookmark: bookmark + 1 } } exports.validate = async () => { diff --git a/packages/server/src/integrations/utils.ts b/packages/server/src/integrations/utils.ts index e662d83d52..a0f2b764bc 100644 --- a/packages/server/src/integrations/utils.ts +++ b/packages/server/src/integrations/utils.ts @@ -224,6 +224,7 @@ function shouldCopySpecialColumn( FieldTypes.ARRAY, FieldTypes.FORMULA, ] + // column has been deleted, remove if (column && !fetchedColumn) { return false }