Skip to content

Conversation

@igorlukanin
Copy link
Member

When multiple queries share the same mutexKey, newer queries invalidate older
ones. Previously, cancelled queries would resolve to undefined because
mutexPromise silently swallowed the MUTEX_ERROR without returning a value.

This caused issues in useCubeQuery where resultSet would unexpectedly reset
to undefined while isLoading remained false.

Changes:

  • Add MutexCancelledError class for explicit mutex cancellation handling
  • Update mutexPromise to throw MutexCancelledError instead of swallowing errors
  • Catch MutexCancelledError in loadMethod and return null (a valid return type)

Check List

  • Tests have been run in packages where changes have been made if available
  • Linter has been run for changed code
  • Tests for the changes have been added if not covered yet
  • Docs have been added / updated if required

Issue Reference this PR resolves

Fixes #10261

Conversation with Claude

claude.txt

…elled by mutex

When multiple queries share the same mutexKey, newer queries invalidate older
  ones. Previously, cancelled queries would resolve to undefined because
  mutexPromise silently swallowed the MUTEX_ERROR without returning a value.

  This caused issues in useCubeQuery where resultSet would unexpectedly reset
  to undefined while isLoading remained false.

  Changes:
  - Add MutexCancelledError class for explicit mutex cancellation handling
  - Update mutexPromise to throw MutexCancelledError instead of swallowing errors
  - Catch MutexCancelledError in loadMethod and return null (a valid return type)

  Fixes #10261
@igorlukanin igorlukanin requested a review from a team as a code owner December 22, 2025 10:58
@igorlukanin igorlukanin removed their assignment Dec 22, 2025
@github-actions github-actions bot added client:core Issues relating to the JavaScript client SDK javascript Pull requests that update Javascript code labels Dec 22, 2025
@johnhunter
Copy link

Thanks for looking into this @igorlukanin - I didn't have a good understanding of the mutex behaviour.

Copy link

@johnhunter johnhunter left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solution makes sense to me. Just the type fallout to resolve.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses an issue where queries cancelled by mutex operations were resolving to undefined, causing unexpected behavior in components like useCubeQuery. The fix introduces explicit error handling for mutex cancellations and returns null instead.

Key changes:

  • Introduces MutexCancelledError class to explicitly represent mutex cancellation events
  • Updates mutexPromise function to throw MutexCancelledError instead of silently swallowing errors
  • Adds error handling in loadMethod to catch MutexCancelledError and return null

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

.then(requestInstance => mutexPromise(requestInstance.subscribe(loadImpl)))
.catch((error) => {
if (error instanceof MutexCancelledError) {
return null;
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The promise chain now returns null when MutexCancelledError is caught, but the public method signatures that call loadMethod (e.g., load, sql, meta, dryRun, cubeSql) don't include null in their return types. For example, the load method signature declares Promise<ResultSet<...>> but can now return Promise<ResultSet<...> | null>. This creates a type safety issue where consumers of the API may not handle the null case properly.

Consider updating all method signatures that use loadMethod to reflect that they can return null, or document this behavior explicitly.

Suggested change
return null;
// Propagate mutex cancellation as a rejected promise instead of resolving to null,
// so that the promise's resolved type remains consistent with public method signatures.
throw error;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

client:core Issues relating to the JavaScript client SDK javascript Pull requests that update Javascript code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

@cubejs-client/react cubeApi.load sometimes resolves to undefined - overwriting the resultSet from useCubeQuery

4 participants