{"record":{"id":"05d221344b76229f","repo":"cube-js/cube","slug":"query-was-cancelled","errorCode":null,"errorMessage":"Query was cancelled","messagePattern":"Query was cancelled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"packages/cubejs-athena-driver/src/AthenaDriver.ts","lineNumber":277,"sourceCode":"  }\n\n  /**\n   * Executes query and returns table memory data that includes rows\n   * and queried fields types.\n   * Returns a cancelable promise that will stop the Athena query on cancel.\n   */\n  public memory(\n    query: string,\n    values: unknown[],\n  ): MaybeCancelablePromise<DownloadTableMemoryData & { types: TableStructure }> {\n    let qid: AthenaQueryId | null = null;\n    let cancelled = false;\n\n    const promise: any = (async () => {\n      qid = await this.startQuery(query, values);\n      if (cancelled) {\n        await this.stopQuery(qid);\n        throw new Error('Query was cancelled');\n      }\n      await this.waitForSuccess(qid, () => cancelled);\n      const iter = this.lazyRowIterator(qid, query, true);\n      const types = <TableStructure><unknown>((await iter.next()).value);\n      const rows: Row[] = [];\n      for await (const row of iter) {\n        if (cancelled) throw new Error('Query was cancelled');\n        rows.push(<Row>row);\n      }\n      return { types, rows };\n    })();\n\n    promise.cancel = async () => {\n      cancelled = true;\n      if (qid) {\n        await this.stopQuery(qid);\n      }\n    };","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/cube-js/cube/blob/7d981676b36392fec34088b9afab6bdcad40207c/packages/cubejs-athena-driver/src/AthenaDriver.ts#L259-L295","documentation":"AthenaDriver.downloadQueryResults runs the query inside a cancelable async promise. If `cancel()` is invoked (setting `cancelled = true`) after `startQuery` resolves but before execution finishes, the promise stops the query and throws 'Query was cancelled'. The first check happens immediately after startQuery.","triggerScenarios":"Caller calls promise.cancel() on the promise returned by downloadQueryResults while startQuery is still pending, so the post-start cancellation check fires.","commonSituations":"User aborts a download in the UI, request timeouts in the orchestrator cancelling in-flight queries, or Cube shutting down and cancelling queued driver work.","solutions":["This is expected cancellation flow — no fix needed unless it occurs unexpectedly","If unexpected, audit callers invoking cancel() (timeouts, connection close) and raise their limits","Handle the error gracefully in consuming code by checking the message before surfacing to users"],"exampleFix":"// before\nconst rows = await driver.downloadQueryResults(query, values)\n// after\ntry {\n  const rows = await driver.downloadQueryResults(query, values)\n} catch (e) {\n  if (e.message !== 'Query was cancelled') throw e\n  // treat as abort, not failure\n}","handlingStrategy":"try-catch","validationCode":"if (isCancelledBeforeStart) { // skip calling the driver at all\n  throw new AbortError()\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = await driver.downloadQueryResults(query, values)\n} catch (e) {\n  if (e && e.message === 'Query was cancelled') return /* treat as abort */\n  throw e\n}","preventionTips":["Set realistic orchestrator timeouts so queries are not cancelled mid-flight","Keep a reference to cancelable promises and only cancel intentionally","Treat cancellation errors as a distinct control-flow code path in your data layer"],"tags":["athena","cancellation","aws"],"backgroundTag":"query-cancelled","analyzedSha":"7d981676b36392fec34088b9afab6bdcad40207c","analyzedAt":"2026-09-02T03:45:10.400Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}