Skip to content

Commit 2d7388d

Browse files
committed
feat: Enhance analytics error handling and logging in ExecutionStore
1 parent ae90e04 commit 2d7388d

1 file changed

Lines changed: 59 additions & 0 deletions

File tree

apps/api/src/stores/execution-store.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,22 @@ export class ExecutionStore {
137137
*/
138138
private writeToAnalytics(record: SaveExecutionRecord): void {
139139
try {
140+
if (!this.env.EXECUTIONS) {
141+
console.warn(
142+
`ExecutionStore.writeToAnalytics: EXECUTIONS binding not available - skipping analytics write`
143+
);
144+
return;
145+
}
146+
140147
const durationMs =
141148
record.endedAt && record.startedAt
142149
? record.endedAt.getTime() - record.startedAt.getTime()
143150
: 0;
144151

152+
console.log(
153+
`ExecutionStore.writeToAnalytics: Writing execution ${record.id} (status: ${record.status}) to dataset ${this.getDatasetName()}`
154+
);
155+
145156
this.env.EXECUTIONS.writeDataPoint({
146157
indexes: [record.organizationId, record.id],
147158
blobs: [
@@ -165,9 +176,25 @@ export class ExecutionStore {
165176
* Query Analytics Engine using SQL API
166177
*/
167178
private async queryAnalytics(sql: string): Promise<any[]> {
179+
// Validate required credentials
180+
if (!this.env.CLOUDFLARE_ACCOUNT_ID || !this.env.CLOUDFLARE_API_TOKEN) {
181+
console.error(
182+
`ExecutionStore.queryAnalytics: Missing credentials - CLOUDFLARE_ACCOUNT_ID: ${!!this.env.CLOUDFLARE_ACCOUNT_ID}, CLOUDFLARE_API_TOKEN: ${!!this.env.CLOUDFLARE_API_TOKEN}`
183+
);
184+
throw new Error(
185+
"Analytics Engine queries require CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN to be configured. " +
186+
"In development: add to .dev.vars file. " +
187+
"In production: use 'wrangler secret put' to set these values."
188+
);
189+
}
190+
168191
try {
169192
const url = `https://api.cloudflare.com/client/v4/accounts/${this.env.CLOUDFLARE_ACCOUNT_ID}/analytics_engine/sql`;
170193

194+
console.log(
195+
`ExecutionStore.queryAnalytics: Querying dataset with account ID ${this.env.CLOUDFLARE_ACCOUNT_ID.substring(0, 8)}...`
196+
);
197+
171198
const response = await fetch(url, {
172199
method: "POST",
173200
headers: {
@@ -178,6 +205,19 @@ export class ExecutionStore {
178205

179206
if (!response.ok) {
180207
const error = await response.text();
208+
console.error(
209+
`ExecutionStore.queryAnalytics: HTTP ${response.status} - ${error}`
210+
);
211+
212+
// Check for common permission issues
213+
if (response.status === 401 || response.status === 403) {
214+
throw new Error(
215+
`Analytics Engine query authentication failed (${response.status}). ` +
216+
`Verify your API token has "Account Analytics: Read" permission. ` +
217+
`Error: ${error}`
218+
);
219+
}
220+
181221
throw new Error(
182222
`Analytics query failed: ${response.statusText} - ${error}`
183223
);
@@ -211,6 +251,10 @@ export class ExecutionStore {
211251
try {
212252
const dataset = this.getDatasetName();
213253

254+
console.log(
255+
`ExecutionStore.readFromAnalytics: Querying ${dataset} for execution ${id}`
256+
);
257+
214258
const sql = `
215259
SELECT *
216260
FROM ${dataset}
@@ -223,12 +267,19 @@ export class ExecutionStore {
223267
const rows = await this.queryAnalytics(sql);
224268

225269
if (rows.length === 0) {
270+
console.log(
271+
`ExecutionStore.readFromAnalytics: No data found for execution ${id}`
272+
);
226273
return undefined;
227274
}
228275

229276
const row = rows[0];
230277
const timestamp = new Date(row.timestamp);
231278

279+
console.log(
280+
`ExecutionStore.readFromAnalytics: Found execution ${id} with status ${row.blob3}`
281+
);
282+
232283
return {
233284
id: row.index2,
234285
workflowId: row.blob1,
@@ -273,6 +324,10 @@ export class ExecutionStore {
273324
const limit = options?.limit ?? 20;
274325
const offset = options?.offset ?? 0;
275326

327+
console.log(
328+
`ExecutionStore.listFromAnalytics: Querying ${dataset} for org ${organizationId.substring(0, 8)}... (limit: ${limit}, offset: ${offset})`
329+
);
330+
276331
const sql = `
277332
SELECT *
278333
FROM ${dataset}
@@ -283,6 +338,10 @@ export class ExecutionStore {
283338

284339
const rows = await this.queryAnalytics(sql);
285340

341+
console.log(
342+
`ExecutionStore.listFromAnalytics: Found ${rows.length} executions`
343+
);
344+
286345
return rows.map((row) => {
287346
const timestamp = new Date(row.timestamp);
288347
return {

0 commit comments

Comments
 (0)