Skip to content

chore: add dsl version validation for app computation cache#40301

Merged
dvj1988 merged 9 commits intoreleasefrom
chore/app-computation-cache-error-handling
Apr 21, 2025
Merged

chore: add dsl version validation for app computation cache#40301
dvj1988 merged 9 commits intoreleasefrom
chore/app-computation-cache-error-handling

Conversation

@dvj1988
Copy link

@dvj1988 dvj1988 commented Apr 17, 2025

Description

This PR adds dsl version to the app computation cache. If there is a mismatch in dsl version the cache is updated with the new value.

Change also includes error handling and reporting for cases when there are exceptions while fetching the cache.

Fixes #Issue Number
or
Fixes Issue URL

Warning

If no issue exists, please create an issue first, and check with the maintainers if the issue is valid.

Automation

/ok-to-test tags="@tag.All"

🔍 Cypress test results

Tip

🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
Workflow run: https://github.com/appsmithorg/appsmith/actions/runs/14533292018
Commit: fadb0c5
Cypress dashboard.
Tags: @tag.All
Spec:


Fri, 18 Apr 2025 11:07:11 UTC

Communication

Should the DevRel and Marketing teams inform users about this change?

  • Yes
  • No

Summary by CodeRabbit

  • New Features

    • Added explicit DSL version tracking to application state and evaluation context for improved cache validation.
  • Bug Fixes

    • Improved error handling for cache operations, ensuring errors are logged and recorded without disrupting core functionality.
    • Enhanced cache validation to prevent usage of invalid or mismatched cache entries.
  • Tests

    • Expanded and updated test coverage for cache validity, error scenarios, and DSL version handling.
  • Refactor

    • Strengthened cache property validation and error propagation for more robust caching behavior.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 17, 2025

Walkthrough

This change introduces stricter validation and explicit handling of a new dslVersion property throughout the application's computation cache mechanisms. The cache logic now requires and verifies the presence of a valid dslVersion in cache properties and cached results. New validation methods and error handling for cache operations are implemented, ensuring that errors are logged and propagated rather than silently ignored. The evaluation saga and related selectors are updated to include the DSL version in evaluation contexts. Test suites are enhanced to validate these new requirements and error scenarios, and error handling is improved across worker and dependency map modules.

Changes

File(s) Change Summary
app/client/src/ce/selectors/entitiesSelector.ts Added getCurrentPageDSLVersion selector to extract the current DSL version from canvas widgets.
app/client/src/utils/DynamicBindingUtils.ts Added CACHE_ERROR to EvalErrorTypes enum.
app/client/src/sagas/EvalErrorHandler.ts Added handling for EvalErrorTypes.CACHE_ERROR, logging and capturing the error.
app/client/src/sagas/EvaluationsSaga.ts, app/client/src/ce/selectors/entitiesSelector.ts Updated evaluateTreeSaga to include DSL version in evaluation requests using the new selector.
app/client/src/sagas/EvaluationsSaga.test.ts Updated tests to mock and verify inclusion of dslVersion in evaluation context.
app/client/src/workers/common/AppComputationCache/types.ts Extended ICacheProps with timestamp, instanceId, and dslVersion; introduced IValidatedCacheProps.
app/client/src/workers/common/AppComputationCache/index.ts Refactored cache logic to require and validate dslVersion, added robust error handling, new validation methods, and a static reset method.
app/client/src/workers/common/AppComputationCache.test.ts Enhanced tests to cover dslVersion validation, cache validity, error handling, and related helper methods.
app/client/src/workers/Evaluation/__tests__/evaluation.test.ts,
app/client/src/workers/Evaluation/evalTreeWithChanges.test.ts,
app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts
Updated test setups to include dslVersion in evaluator context.
app/client/src/workers/common/DataTreeEvaluator/index.ts Added error handling for cache fetch/computation in setupFirstTree, falling back to direct computation on error.
app/client/src/workers/common/DependencyMap/index.ts Wrapped cache get/set in try-catch, logging and recording CACHE_ERROR on failure.

Sequence Diagram(s)

sequenceDiagram
    participant S as Saga (evaluateTreeSaga)
    participant Sel as Selector (getCurrentPageDSLVersion)
    participant W as Worker (evalWorker)
    S->>Sel: Select DSL version from state
    Sel-->>S: Return dslVersion
    S->>W: Send evaluation request with dslVersion in cacheProps
    W-->>S: Return evaluation result
Loading
sequenceDiagram
    participant E as DataTreeEvaluator
    participant C as AppComputationCache
    participant L as Logger
    E->>C: fetchOrCompute(allKeys, cacheProps)
    alt Cache fetch success
        C-->>E: Return cached or computed allKeys
    else Cache fetch error
        C-->>L: Log error, throw exception
        E->>E: Catch error, record CACHE_ERROR, compute allKeys directly
    end
Loading

Possibly related PRs

  • appsmithorg/appsmith#40170: Adds a new cache error case to evalErrorHandler, directly related to the enhanced error handling for cache errors in this PR.

Poem

Cache now checks its version,
No more silent submersion.
Errors are caught,
And bugs are fought,
With DSL in every assertion!

🗝️✨

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the skip-changelog Adding this label to a PR prevents it from being listed in the changelog label Apr 17, 2025
@dvj1988 dvj1988 added the ok-to-test Required label for CI label Apr 17, 2025
@github-actions
Copy link

🔴🔴🔴 Cyclic Dependency Check:

This PR has increased the number of cyclic dependencies by 18, when compared with the release branch.

Refer this document to identify the cyclic dependencies introduced by this PR.

You can view the dependency diff in the run log. Look for the check-cyclic-dependencies job in the run.

Diljit VJ added 2 commits April 17, 2025 16:30
…om:appsmithorg/appsmith into chore/app-computation-cache-error-handling
@dvj1988
Copy link
Author

dvj1988 commented Apr 17, 2025

/build-deploy-preview skip-tests=true

@github-actions
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/14514190262.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40301.
recreate: .

@github-actions
Copy link

Deploy-Preview-URL: https://ce-40301.dp.appsmith.com

@dvj1988
Copy link
Author

dvj1988 commented Apr 17, 2025

/build-deploy-preview skip-tests=true

@github-actions
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/14519646998.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40301.
recreate: .

@github-actions
Copy link

Deploy-Preview-URL: https://ce-40301.dp.appsmith.com

@dvj1988
Copy link
Author

dvj1988 commented Apr 18, 2025

/build-deploy-preview skip-tests=true

@github-actions
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/14529328623.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40301.
recreate: .

@github-actions
Copy link

Deploy-Preview-URL: https://ce-40301.dp.appsmith.com

cacheProps,
cacheName: EComputationCacheName.DEPENDENCY_MAP,
});
} catch (error) {
Copy link
Contributor

@vsvamsi1 vsvamsi1 Apr 18, 2025

Choose a reason for hiding this comment

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

So the changes over here is if we are unable to retrieve, we would get a null in the dependencyMapCache and subseqeunetly reconstruct the dependencyMap. Is my understanding correct @diljit.

Copy link
Author

@dvj1988 dvj1988 Apr 18, 2025

Choose a reason for hiding this comment

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

If the cache is invalid or not present the appcomputation cache will send back null. The catch block is added so the can capture the errors thrown by the app computation cache.

const fallbackResult = await computeFn();

return fallbackResult;
loglevel.error(error);
Copy link
Contributor

@vsvamsi1 vsvamsi1 Apr 18, 2025

Choose a reason for hiding this comment

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

If it can't retrieve it, it can recompute the result like what the code was earlier doing.

Copy link
Author

Choose a reason for hiding this comment

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

I have moved the fallback logic to where it is consumed. We need to throw the error here so that we can catch it where it is used. This would help us then send the error to the main catch block in eval tree and then eventually send it back to the main thread.

@dvj1988
Copy link
Author

dvj1988 commented Apr 18, 2025

/build-deploy-preview skip-tests=true

@github-actions
Copy link

Deploying Your Preview: https://github.com/appsmithorg/appsmith/actions/runs/14533303535.
Workflow: On demand build Docker image and deploy preview.
skip-tests: true.
env: ``.
PR: 40301.
recreate: .

@github-actions
Copy link

Deploy-Preview-URL: https://ce-40301.dp.appsmith.com

@dvj1988 dvj1988 marked this pull request as ready for review April 21, 2025 03:41
@dvj1988 dvj1988 requested a review from ApekshaBhosale as a code owner April 21, 2025 03:41
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (8)
app/client/src/workers/common/AppComputationCache/types.ts (1)

12-15: Clarify dslVersion semantics & promote immutability

  1. ICacheProps.dslVersion is number | null while timestamp is string | undefined.
    Using null for missing but undefined for other optional fields introduces a
    tri‑state (undefined vs null vs valid). Prefer one convention – e.g. make it
    number | undefined and treat “not supplied” uniformly.

  2. Consider marking all fields in IValidatedCacheProps as readonly to prevent
    accidental mutation after validation.

These tweaks tighten typing without altering runtime behaviour.

Also applies to: 17-24

app/client/src/workers/common/DependencyMap/index.ts (2)

66-82: Bubble cache‑layer failures when dependency map is mandatory

The new try‑catch ensures the app continues even when the cache layer throws, but
silently discarding the cache means we might repeatedly recompute the dependency
map, adding latency. At minimum, consider logging at error level (or re‑throw
when process.env.NODE_ENV !== "production") so the issue surfaces quickly.

Extracting the cache‑access pattern into a helper (e.g. safeGetCachedResult)
would also remove the duplicated try‑catch here and in DataTreeEvaluator.


121-134: Symmetric error handling for cacheComputationResult

cacheComputationResult is wrapped in a try‑catch exactly like the read path—
great. You already push a CACHE_ERROR, but unlike the read branch you do not
log the original error. Adding a log.error (or Sentry breadcrumb) will help
diagnose write‑side failures that otherwise stay silent.

app/client/src/workers/common/AppComputationCache/AppComputationCache.test.ts (1)

542-563: Test is in the wrong describe‑block

The “should not cache result when dsl version is invalid” test lives inside the
fetchOrCompute suite but directly calls cacheComputationResult. Moving it to
the neighbouring cacheComputationResult describe keeps the test hierarchy
intuitive.

No functional change – purely organisational.

app/client/src/workers/common/AppComputationCache/index.ts (4)

61-64: Consolidate mode validation with the configuration source

isAppModeValid duplicates knowledge already stored in appModeConfig. Instead of maintaining two separate allow‑lists, reuse the config to remove duplication and the risk of them diverging.

isAppModeValid(appMode: unknown) {
-  return appMode === APP_MODE.PUBLISHED || appMode === APP_MODE.EDIT;
+  return Object.values(this.appModeConfig)
+    .flat()
+    .includes(appMode as APP_MODE);
}

69-74: Timestamp validation is overly strict and brittle

Hard‑coding an ISO‑8601 regex blocks perfectly valid date strings that include a timezone offset (e.g. 2024‑04‑18T10:35:00+05:30). Consider deferring to the built‑in Date.parse() for broader coverage and lower maintenance cost.

-const isoStringRegex = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z$/;
-...
-return isoStringRegex.test(timestamp);
+return !Number.isNaN(Date.parse(timestamp));

76-78: Permit DSL version 0 or document the assumption

dslVersion > 0 silently rejects a legitimate 0.
If 0 is an impossible sentinel, add a clarifying comment. Otherwise use >= 0 to avoid edge‑case cache misses.


312-315: Early‑exit before scanning keys when timestamp is missing

Inside the filter you short‑circuit on !cacheProps.timestamp, but the loop still iterates over every key first. Bail out earlier to avoid unnecessary work on large caches:

-// Get invalid cache keys
-const invalidCacheKeys = cacheKeys.filter((key) => {
-  const keyParts = key.split(AppComputationCache.CACHE_KEY_DELIMITER);
-  ...
-  if (!cacheProps.timestamp) {
-    return false;
-  }
+if (!cacheProps.timestamp) return;
+
+const invalidCacheKeys = cacheKeys.filter((key) => {
+  const keyParts = key.split(AppComputationCache.CACHE_KEY_DELIMITER);
   ...
 });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c8a132f and fadb0c5.

📒 Files selected for processing (13)
  • app/client/src/ce/selectors/entitiesSelector.ts (1 hunks)
  • app/client/src/sagas/EvalErrorHandler.ts (1 hunks)
  • app/client/src/sagas/EvaluationsSaga.test.ts (7 hunks)
  • app/client/src/sagas/EvaluationsSaga.ts (3 hunks)
  • app/client/src/utils/DynamicBindingUtils.ts (1 hunks)
  • app/client/src/workers/Evaluation/__tests__/evaluation.test.ts (1 hunks)
  • app/client/src/workers/Evaluation/evalTreeWithChanges.test.ts (1 hunks)
  • app/client/src/workers/common/AppComputationCache/AppComputationCache.test.ts (18 hunks)
  • app/client/src/workers/common/AppComputationCache/index.ts (13 hunks)
  • app/client/src/workers/common/AppComputationCache/types.ts (1 hunks)
  • app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts (3 hunks)
  • app/client/src/workers/common/DataTreeEvaluator/index.ts (1 hunks)
  • app/client/src/workers/common/DependencyMap/index.ts (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
app/client/src/sagas/EvaluationsSaga.test.ts (1)
app/client/src/ce/selectors/entitiesSelector.ts (1)
  • getCurrentPageDSLVersion (1808-1810)
app/client/src/sagas/EvalErrorHandler.ts (2)
app/client/src/instrumentation/sendFaroErrors.ts (1)
  • captureException (5-19)
app/client/src/utils/Analytics/sentry.ts (1)
  • captureException (19-21)
app/client/src/ce/selectors/entitiesSelector.ts (1)
app/client/src/ce/reducers/index.tsx (1)
  • AppState (98-191)
app/client/src/sagas/EvaluationsSaga.ts (1)
app/client/src/ce/selectors/entitiesSelector.ts (1)
  • getCurrentPageDSLVersion (1808-1810)
app/client/src/workers/common/DataTreeEvaluator/index.ts (2)
app/client/src/workers/common/AppComputationCache/index.ts (1)
  • appComputationCache (348-348)
app/client/src/ce/workers/Evaluation/evaluationUtils.ts (1)
  • getAllPaths (545-568)
app/client/src/workers/common/AppComputationCache/index.ts (2)
app/client/src/utils/helpers.tsx (1)
  • isString (556-558)
app/client/src/workers/common/AppComputationCache/types.ts (2)
  • ICacheProps (8-15)
  • IValidatedCacheProps (17-24)
🪛 Biome (1.9.4)
app/client/src/workers/common/AppComputationCache/index.ts

[error] 11-11: Do not shadow the global "isFinite" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (16)
app/client/src/utils/DynamicBindingUtils.ts (1)

164-164: Adding new CACHE_ERROR type to support cache validation enhancements

This addition of a new error type will be used for error handling in cache operations across various modules, allowing consistent handling of cache-related errors.

app/client/src/ce/selectors/entitiesSelector.ts (1)

1808-1810: Added selector for retrieving page DSL version for cache validation

This new selector extracts the DSL version from the canvas widget state, which will be used to ensure cache validity in the evaluation process. Good implementation of a simple and focused selector.

app/client/src/workers/Evaluation/__tests__/evaluation.test.ts (1)

591-591: Updated test to include dslVersion parameter in setupFirstTree

The test has been properly updated to provide the dslVersion in the options object, aligning with the changes in cache validation requirements.

app/client/src/workers/common/DataTreeEvaluator/dataTreeEvaluator.test.ts (3)

293-293: Added dslVersion parameter to test setup

The test setup has been updated to include the dslVersion parameter, ensuring proper test coverage for the enhanced cache validation mechanism.


395-395: Added dslVersion parameter to test setup

Consistent update to include the dslVersion parameter in another test block, maintaining proper test coverage.


459-459: Added dslVersion parameter to test setup

Added the dslVersion parameter to complete the necessary test updates for the array accessor dependency handling tests, ensuring all test cases correctly include the new required parameter.

app/client/src/workers/Evaluation/evalTreeWithChanges.test.ts (1)

203-203: Add DSL version to test setup

Including dslVersion in the test context aligns with the new validation requirements for app computation cache.

app/client/src/sagas/EvaluationsSaga.test.ts (4)

15-18: Import getCurrentPageDSLVersion selector

Proper inclusion of the DSL version selector for testing the cache validation feature.


65-65: Mock DSL version selector for test

Correctly mocks the DSL version selector to return a fixed value for test predictability.


74-74: Add DSL version to cacheProps in expected worker request

Verifies that the evaluation worker receives the DSL version in its cache properties.


113-113: Include DSL version in remaining test cases

Ensures consistent DSL version verification across all relevant test scenarios.

Also applies to: 122-122, 170-170, 179-179

app/client/src/sagas/EvalErrorHandler.ts (1)

330-334: Add dedicated error handler for cache errors

Properly handles cache errors with specific logging and error tracking. This is essential for diagnosing issues with the new DSL version cache validation.

app/client/src/sagas/EvaluationsSaga.ts (3)

80-80: Import getCurrentPageDSLVersion selector

Adds the necessary selector to retrieve the current page's DSL version.


273-273: Select current page DSL version from state

Retrieves the DSL version from Redux state for inclusion in cache validation.


284-284: Include DSL version in cache properties

Passes the DSL version to the evaluation worker as part of cache validation properties.

app/client/src/workers/common/AppComputationCache/index.ts (1)

340-345: Expose resetInstance only in test environments

Resetting the singleton at runtime outside of tests can break cache consistency. Guard the method behind process.env.NODE_ENV === "test" or move it to a dedicated test helper to avoid accidental misuse.

Comment on lines +305 to +319
try {
this.allKeys = await appComputationCache.fetchOrCompute({
cacheProps,
cacheName: EComputationCacheName.ALL_KEYS,
computeFn: () => getAllPaths(unEvalTreeWithStrigifiedJSFunctions),
});
} catch (error) {
this.errors.push({
type: EvalErrorTypes.CACHE_ERROR,
message: (error as Error).message,
stack: (error as Error).stack,
});

this.allKeys = getAllPaths(unEvalTreeWithStrigifiedJSFunctions);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid running the costly getAllPaths twice on cache‑failure

Inside the catch block you recompute this.allKeys with a direct call to getAllPaths, even though fetchOrCompute will already have executed the very same computeFn once before propagating the error.
That means the traversal work is done twice when the cache layer is unhealthy.

A small refactor can keep the first computation result and still record the error:

-} catch (error) {
-  this.errors.push({
-    type: EvalErrorTypes.CACHE_ERROR,
-    message: (error as Error).message,
-    stack: (error as Error).stack,
-  });
-
-  this.allKeys = getAllPaths(unEvalTreeWithStrigifiedJSFunctions);
-}
+} catch (error: unknown) {
+  this.errors.push({
+    type: EvalErrorTypes.CACHE_ERROR,
+    message: (error as Error).message,
+    stack: (error as Error).stack,
+  });
+  /* `fetchOrCompute` already executed computeFn; reuse the fallback value if it
+     was returned, otherwise compute locally. */
+  this.allKeys =
+    (error as any)?.result ??
+    getAllPaths(unEvalTreeWithStrigifiedJSFunctions);
+}

This keeps error logging intact while saving one full tree walk.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +11 to 12
import { isFinite, isNumber, isString } from "lodash";

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Rename isFinite import to avoid shadowing the global API

Importing isFinite from lodash shadows the global isFinite function. This triggers lint warnings (noShadowRestrictedNames) and is easy to confuse when reading the code.

-import { isFinite, isNumber, isString } from "lodash";
+import { isFinite as _isFinite, isNumber, isString } from "lodash";

…and update the two call‑sites (isDSLVersionValid) to use _isFinite.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { isFinite, isNumber, isString } from "lodash";
// app/client/src/workers/common/AppComputationCache/index.ts
-import { isFinite, isNumber, isString } from "lodash";
+import { isFinite as _isFinite, isNumber, isString } from "lodash";
🧰 Tools
🪛 Biome (1.9.4)

[error] 11-11: Do not shadow the global "isFinite" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

Comment on lines +187 to 204
/**
* Checks if the cached value is valid
* @returns - A boolean indicating whether the cached value is valid
*/
isCacheValid<T>(
cachedValue: ICachedData<T> | null,
cacheProps: IValidatedCacheProps,
): cachedValue is ICachedData<T> {
if (isNull(cachedValue)) {
return false;
}

if (!cachedValue.dslVersion) {
return false;
}

return cachedValue.dslVersion === cacheProps.dslVersion;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

isCacheValid ignores other invalidating props

The method only checks dslVersion. If any of the validated properties (appId, pageId, timestamp, etc.) ever change without altering the key (e.g. a future refactor), stale data could leak through. At minimum compare cachedValue.dslVersion and guard against a null/undefined mismatch explicitly:

-return cachedValue.dslVersion === cacheProps.dslVersion;
+return (
+  cachedValue.dslVersion !== undefined &&
+  cachedValue.dslVersion === cacheProps.dslVersion
+);

Long‑term, consider encoding all props that affect validity into the key itself to remove this class of errors entirely.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
/**
* Checks if the cached value is valid
* @returns - A boolean indicating whether the cached value is valid
*/
isCacheValid<T>(
cachedValue: ICachedData<T> | null,
cacheProps: IValidatedCacheProps,
): cachedValue is ICachedData<T> {
if (isNull(cachedValue)) {
return false;
}
if (!cachedValue.dslVersion) {
return false;
}
return cachedValue.dslVersion === cacheProps.dslVersion;
}
/**
* Checks if the cached value is valid
* @returns - A boolean indicating whether the cached value is valid
*/
isCacheValid<T>(
cachedValue: ICachedData<T> | null,
cacheProps: IValidatedCacheProps,
): cachedValue is ICachedData<T> {
if (isNull(cachedValue)) {
return false;
}
if (!cachedValue.dslVersion) {
return false;
}
return (
cachedValue.dslVersion !== undefined &&
cachedValue.dslVersion === cacheProps.dslVersion
);
}

@dvj1988 dvj1988 merged commit c580cfd into release Apr 21, 2025
86 checks passed
@dvj1988 dvj1988 deleted the chore/app-computation-cache-error-handling branch April 21, 2025 07:29
@coderabbitai coderabbitai bot mentioned this pull request May 2, 2025
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ok-to-test Required label for CI skip-changelog Adding this label to a PR prevents it from being listed in the changelog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants