Skip to content

fix: overflowed keyId issue#2976

Merged
chronark merged 7 commits intomainfrom
fix-overflowed-key-issue
Mar 17, 2025
Merged

fix: overflowed keyId issue#2976
chronark merged 7 commits intomainfrom
fix-overflowed-key-issue

Conversation

@ogzhanolguncu
Copy link
Contributor

@ogzhanolguncu ogzhanolguncu commented Mar 17, 2025

What does this PR do?

Fixes # (issue)

If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features
    • Enhanced API data retrieval and validation to ensure only active, non-deleted information is used.
    • Refined analytics for key activity, logs, and timeseries data with improved filtering and error handling for more reliable insights.
    • Introduced batch processing for verification metrics, boosting efficiency and accuracy when handling large datasets.
    • Added a maximum limit on the number of filters for key IDs in analytics queries to improve validation logic.
  • Bug Fixes
    • Improved error handling in timeseries data processing to prevent runtime errors.
  • Chores
    • Removed unnecessary error handling from timeseries query execution for streamlined responses.

@changeset-bot
Copy link

changeset-bot bot commented Mar 17, 2025

⚠️ No Changeset found

Latest commit: 1096a83

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Mar 17, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
dashboard ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 17, 2025 2:24pm
engineering ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 17, 2025 2:24pm
play ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 17, 2025 2:24pm
www ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 17, 2025 2:24pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 17, 2025

📝 Walkthrough

Walkthrough

The pull request introduces a new asynchronous function, getApi, for retrieving API records with specific filtering based on apiId and workspaceId. Several router modules have been updated to utilize this function for validating API existence and key authentication before proceeding with further logic. Additionally, error handling has been streamlined in one module while robust filtering has been added in others. In the ClickHouse integrations, a new property (key_ids) has been added to the timeseries schema, and batch processing for verification timeseries queries has been implemented to handle large datasets efficiently.

Changes

File(s) Summary of Changes
apps/dashboard/lib/trpc/routers/api/keys/api-query.ts Added new async function getApi to query API data filtering by apiId and workspaceId with error logging and TRPCError handling.
apps/dashboard/lib/trpc/routers/api/keys/query-active-keys-timeseries/index.ts
apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/index.ts
Updated to call getApi for API retrieval; included validations for API existence and key authentication; modified error handling and filtering logic.
apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts Removed error handling for ClickHouse query results and now directly returns the query result with granularity.
internal/clickhouse/src/keys/active_keys.ts Added an optional key_ids property to the timeseries schema and updated SQL to include groupArray(DISTINCT key_id) for distinct key IDs.
internal/clickhouse/src/verifications.ts Introduced batchVerificationTimeseries to process verification queries in batches and added a mergeVerificationTimeseriesResults helper; updated multiple exported query functions to use the batching mechanism.
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/charts/bar-chart/query-timeseries.schema.ts Added constant MAX_KEYID_COUNT to limit keyIds filters to a maximum of 15.
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/query-logs.schema.ts Imported MAX_KEYID_COUNT and updated keyIds schema to enforce the maximum length constraint.

Possibly related PRs

  • feat: add more granular fetch options for timeseries #2736: The changes in the main PR are related to the introduction of the getApi function, which is utilized in the retrieved PR to fetch API details.
  • feat: new filter logic #2804: The changes in the main PR, which introduce a new getApi function for querying API data, are related to the retrieved PR as it also utilizes the getApi function to enhance filtering logic in various components.
  • feat: Add default bytes and prefix #2146: The changes in the main PR, which introduce a new getApi function for querying API data, are related to the retrieved PR as it also utilizes the getApi function to enhance the logic for retrieving API details in other components.

Suggested labels

Bug, Good first issue

Suggested reviewers

  • mcstepp
  • chronark
  • perkinsjr

Tip

⚡🧪 Multi-step agentic review comment chat (experimental)
  • We're introducing multi-step agentic chat in review comments. This experimental feature enhances review discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments.
    - To enable this feature, set early_access to true under in the settings.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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
Copy link
Contributor

github-actions bot commented Mar 17, 2025

Thank you for following the naming conventions for pull request titles! 🙏

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: 0

🧹 Nitpick comments (3)
apps/dashboard/lib/trpc/routers/api/keys/query-active-keys-timeseries/index.ts (2)

29-35: Surface more detailed error messages.
Throwing an internal server error when clickhouseResult is falsy or contains err is correct from a flow standpoint. However, more context (like the actual error message from clickhouseResult.err) might help troubleshooting.

-  message: "Something went wrong when fetching data from ClickHouse.",
+  message: clickhouseResult?.err?.message || "Something went wrong when fetching data from ClickHouse.",

50-60: Query keys based on aggregated key IDs.
The queryApiKeys call effectively filters keys for the names/identities logic. This is a good example of referencing multiple filters in a single query. Watch out for performance if allKeyIds grows large.

Consider chunking the queries or introducing a maximum limit if allKeyIds can become extremely large.

internal/clickhouse/src/verifications.ts (1)

403-443: Implement batch-based timeseries fetching.
Your batchVerificationTimeseries function is a solid approach for handling large keyIds arrays. Using Promise.allSettled ensures partial success even if some batches fail. Consider logging or handling partial failures more explicitly rather than returning an empty result for failing batches.

+ // Example simpler logging approach:
console.error(`Batch ${batchIndex} query failed:`, error);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b88a058 and fe5f81f.

📒 Files selected for processing (6)
  • apps/dashboard/lib/trpc/routers/api/keys/api-query.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/api/keys/query-active-keys-timeseries/index.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/index.ts (2 hunks)
  • apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (1 hunks)
  • internal/clickhouse/src/keys/active_keys.ts (2 hunks)
  • internal/clickhouse/src/verifications.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (18)
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Test Packages / Test ./packages/hono
  • GitHub Check: Test Packages / Test ./packages/nextjs
  • GitHub Check: Test Packages / Test ./internal/keys
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Packages / Test ./internal/hash
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Packages / Test ./internal/id
  • GitHub Check: Test Packages / Test ./internal/billing
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: Test Packages / Test ./internal/encryption
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (22)
apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (1)

30-30: Simplified error handling approach

The error handling logic for result.err has been removed, returning the result directly. This simplification is part of a broader refactoring and aligns with the fix for the keyId overflow issue, assuming that error handling is now managed elsewhere in the call chain.

apps/dashboard/lib/trpc/routers/api/keys/api-query.ts (1)

330-352: Well-implemented API retrieval function

The new getApi function efficiently fetches API data with minimal columns, properly handles database errors, and validates that the API exists and has key authentication enabled. This is a good abstraction that centralizes API retrieval logic.

internal/clickhouse/src/keys/active_keys.ts (2)

50-50: Improved schema with key_ids tracking

Adding the optional key_ids array to the schema is appropriate for tracking which specific keys were active in a time period, which supports the fix for the keyId overflow issue.


147-148: Enhanced query to track distinct key IDs

The SQL query now collects distinct key IDs with groupArray(DISTINCT key_id), which will help with debugging and tracking key activity. This properly supports the schema change above.

apps/dashboard/lib/trpc/routers/api/keys/query-overview-logs/index.ts (4)

33-40: Improved API validation with getApi

Using the new getApi function for API validation is more efficient than the previous approach. The clear error message when an API is not found or doesn't have key authentication is helpful for debugging.


50-54: Better separation of filtering responsibilities

The code now only includes keyIds in ClickHouse queries when explicitly provided, while nullifying names and identities filters to handle them in the database layer. This separation of concerns is appropriate and may help address the keyId overflow issue.


72-94: Improved key filtering and mapping logic

The enhanced filtering ensures that logs are only included for keys that exist in both ClickHouse and the database, and have passed all filters. This approach is more robust and can prevent issues with non-existent or invalid keys.


99-99: Fixed pagination accuracy

The hasMore calculation now correctly considers the length of the filtered keysOverviewLogs array rather than just the raw logs from ClickHouse. This ensures pagination works properly even when some logs are filtered out.

apps/dashboard/lib/trpc/routers/api/keys/query-active-keys-timeseries/index.ts (12)

5-5: Import usage looks good.
This import statement concisely brings in both getApi and queryApiKeys, which appear to be used appropriately throughout the file.


11-18: Validate the existence of the API and keyAuth before proceeding.
Throwing a TRPCError when the api or api.keyAuth?.id is not found is a good practice for preventing further processing of invalid data. Just ensure other parts of the code gracefully handle this error.


20-20: Destructure transform inputs.
The extraction of transformedInputs and granularity with transformVerificationFilters(input) is a clean approach, keeping the transformation logic separate from business logic.


22-22: Ensure valid granularity keys.
When using clickhouse.verifications.activeKeysTimeseries[granularity], confirm that granularity always maps to a valid property to avoid runtime errors.

Could you run an additional check that ensures granularity is one of the accepted values in activeKeysTimeseries?


26-26: Check for consistent handling of empty arrays.
Currently, if input.keyIds is falsy, keyIds is set to null. Verify whether clickhouse.verifications.activeKeysTimeseries[...] expects an array instead of null. If it can handle null safely, this is fine; otherwise, consider defaulting to an empty array.


36-42: Return null timeseries on empty result set.
This approach of returning null under timeseries when no data is available is straightforward. Ensure that downstream consumers properly handle timeseries: null.


44-49: Accumulate key IDs into a set.
Gathering key IDs from all data points is a neat way to reduce potential duplicates. The usage of (point.key_ids ?? []) is safe-guarding from null/undefined conditions. Nicely done.


61-62: Set creation for quick membership tests.
Transforming the resulting keys to a Set for membership checks is efficient and clean.


63-72: Derive filtered timeseries with minimal overhead.
Mapping over timeseriesWithKeys and filtering with filteredKeyIdSet is a straightforward approach. Just double-check that the point.x alignment does not require further merging logic if data points share an identical timestamp.


74-74: Concise return for filtered timeseries.
Returning { timeseries: filteredTimeseries, granularity } is consistent with the earlier structure.


77-80: Map over raw timeseries results.
Preserving point.x and point.y for the timeseriesData object matches the approach used elsewhere in the code. The minimal transformation ensures good performance.


82-82: Finalize timeseries response.
Consistently returning { timeseries, granularity } keeps the API response format uniform.

internal/clickhouse/src/verifications.ts (2)

445-486: Accumulate results across batches.
Merging points in mergeVerificationTimeseriesResults is well-structured. Summing numeric fields ensures correctness of final aggregated time buckets. Watch out for potential integer overflow if these sums can become very large.


488-523: Procedure-level function wrappers.
Wrapping getHourlyVerificationTimeseries, getTwoHourlyVerificationTimeseries, etc., around batchVerificationTimeseries enforces a consistent interface and ensures all intervals benefit from the batching logic. This is a clean, extensible approach.

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: 0

🧹 Nitpick comments (4)
internal/clickhouse/src/verifications.ts (3)

403-443: Well-implemented batch processing for handling large keyId arrays

The new batchVerificationTimeseries function effectively solves the keyId overflow issue by implementing batch processing. This is a robust solution that handles large datasets by breaking them into manageable chunks.

Two minor improvements to consider:

  1. Line 429 returns res directly if it has no .val property, but this inconsistency could cause type issues in the merger function. Consider standardizing the return type.

  2. Consider adding timeout handling for individual batch queries:

-const batchResults = await Promise.allSettled(
+const batchResults = await Promise.allSettled(
   keyIdBatches.map(async (batchKeyIds, batchIndex) => {
+    // Add timeout to prevent long-running queries
+    return Promise.race([
       const batchArgs = {
         ...args,
         keyIds: batchKeyIds,
       };
       try {
         const res = await createVerificationTimeseriesQuerier(interval)(ch)(batchArgs);
         if (res?.val) {
           return res.val;
         }
         return res; // Return res directly if no .val
       } catch (error) {
         console.error(`Batch ${batchIndex} query failed:`, error);
         return [];
-      }
+      },
+      new Promise((_, reject) => 
+        setTimeout(() => reject(new Error(`Batch ${batchIndex} timed out`)), 30000)
+      )
+    ]);
   }),
 );

445-486: Efficient merge implementation for batch results

The mergeVerificationTimeseriesResults function correctly consolidates results from multiple batches, summing counts for each timestamp and maintaining proper order.

Consider adding null protection for dataPoint.y properties to make the code more resilient:

 if (!existingPoint) {
   mergedMap.set(dataPoint.x, dataPoint);
 } else {
   mergedMap.set(dataPoint.x, {
     x: dataPoint.x,
     y: {
-      total: (existingPoint.y.total ?? 0) + (dataPoint.y.total ?? 0),
+      total: (existingPoint.y?.total ?? 0) + (dataPoint.y?.total ?? 0),
       // Apply similar changes to other properties

This would protect against unexpected data shapes from query results.


425-434: Robust error handling for individual batch queries

The implementation properly catches and logs errors for individual batches without failing the entire operation. This increases resilience when dealing with large datasets.

Consider enhancing error reporting by including more diagnostic information:

 try {
   const res = await createVerificationTimeseriesQuerier(interval)(ch)(batchArgs);
   if (res?.val) {
     return res.val;
   }
   return res; // Return res directly if no .val
 } catch (error) {
-  console.error(`Batch ${batchIndex} query failed:`, error);
+  console.error(
+    `Batch ${batchIndex} query failed (batch size: ${batchKeyIds.length}):`, 
+    error, 
+    { batchKeyIds: batchKeyIds.map(k => k.value).join(',') }
+  );
   return [];
 }
apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (1)

30-33:

Details

❓ Verification inconclusive

Simplified error handling flow by removing explicit error checks.

The code now directly returns the result from the ClickHouse query without checking for errors. This change aligns with similar modifications in other files and streamlines the code flow.

While this simplification makes the code cleaner, ensure that error handling has been moved to a higher level in the application or that the ClickHouse client handles errors appropriately. Otherwise, clients of this API could receive raw errors instead of well-formatted error responses.


🏁 Script executed:

#!/bin/bash
# Check if the ClickHouse verification timeseries function handles errors internally
rg "verifications\.timeseries" -A 10 -B 10 --glob "*.ts" | grep -A 5 -B 5 "err\|error\|throw\|catch"

Length of output: 102


Action: Confirm Centralized Error Handling for ClickHouse Queries

The change in apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (lines 30-33) simplifies error handling by directly returning the ClickHouse query result without explicitly catching errors. This approach is aligned with similar changes elsewhere in the codebase. However, it's important to verify one of the following before proceeding:

  • Centralized Error Handling: Confirm that error handling has been moved to a higher level in the application where raw errors from the ClickHouse client are caught and transformed into well-structured API responses.
  • ClickHouse Client Guarantees: Ensure that the ClickHouse client itself appropriately handles errors internally so that clients of this API do not receive raw error messages.

Since our initial automated search did not yield evidence of explicit error handling within this module, please manually verify that either of the above mechanisms is in place. This will ensure consistency and prevent unhandled errors from propagating to the API consumers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5511e41 and adc782a.

📒 Files selected for processing (4)
  • apps/dashboard/app/(app)/apis/_components/hooks/use-query-timeseries.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (1 hunks)
  • apps/dashboard/lib/trpc/routers/api/overview/query-timeseries/index.ts (1 hunks)
  • internal/clickhouse/src/verifications.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/app/(app)/apis/_components/hooks/use-query-timeseries.ts (1)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2918
File: apps/dashboard/app/(app)/apis/_components/hooks/use-query-timeseries.ts:0-0
Timestamp: 2025-03-12T13:07:07.472Z
Learning: The useFetchVerificationTimeseries hook intentionally uses TIMESERIES_DATA_WINDOW * 24 to create a daily interval (24 hours) instead of the standard 1-hour interval used in other hooks.
⏰ Context from checks skipped due to timeout of 90000ms (16)
  • GitHub Check: Test Packages / Test ./packages/nextjs
  • GitHub Check: Test Packages / Test ./packages/hono
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Packages / Test ./packages/rbac
  • GitHub Check: Build / Build
  • GitHub Check: Test Packages / Test ./internal/hash
  • GitHub Check: Test Packages / Test ./internal/billing
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Packages / Test ./internal/encryption
  • GitHub Check: Test Packages / Test ./internal/id
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (4)
apps/dashboard/app/(app)/apis/_components/hooks/use-query-timeseries.ts (1)

58-60: Added defensive null handling for improved robustness

Adding nullish coalescing operators for both data?.timeseries and data?.granularity improves the code's resilience against undefined values. This prevents potential runtime errors and ensures consistent behavior with sensible defaults.

This change aligns well with the server-side error handling adjustments made in the related files, creating a more robust end-to-end implementation.

internal/clickhouse/src/verifications.ts (2)

488-522: Clean function signature updates maintaining API consistency

All exported timeseries functions have been updated to use the new batch processing approach while maintaining a consistent API interface. This is a good practice that allows for internal implementation changes without breaking external consumers.


409-411: Good performance optimization with conditional batching

The function only activates the batching mechanism when necessary (when keyIds.length > maxBatchSize), which avoids unnecessary complexity for smaller queries.

apps/dashboard/lib/trpc/routers/api/overview/query-timeseries/index.ts (1)

17-20:

Details

✅ Verification successful

Simplified error handling by removing explicit error checks.

Similar to changes in the keyVerificationsTimeseries function, this code now directly returns the result from the ClickHouse query without error validation.

This change creates a consistent pattern across the codebase, but ensure that error handling has been moved elsewhere in the application stack. Otherwise, API consumers might receive unexpected error formats.


🏁 Script executed:

#!/bin/bash
# Check for global error handling middleware or higher-level error handling
rg "errorFormatter|createTRPCRouter|errorHandler" --glob "*.ts" -A 10 -B 10 | grep -A 5 -B 5 "error\|catch"

# Check if there are any patterns of handling ClickHouse errors globally
rg "clickhouse" -A 5 -B 5 --glob "*.ts" | grep -A 3 -B 3 "catch\|try\|error"

Length of output: 4438


Confirm Global Error Handling for TRPC Endpoint

The changes in the query-timeseries endpoint—removing explicit error checks and directly returning the ClickHouse query result—are consistent with similar refactoring (e.g., in keyVerificationsTimeseries). Our investigation shows that errors from ClickHouse queries are caught and reformatted at lower layers (for example, in internal/clickhouse/src/client/client.ts and within other API routes). This suggests that global error handling (likely via TRPC’s router configuration or middleware) is in place.

  • Ensure that the global TRPC error formatter or middleware is applied to this endpoint so that any errors thrown by the ClickHouse client are caught and consistently formatted for API consumers.

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: 0

🧹 Nitpick comments (2)
internal/clickhouse/src/verifications.ts (2)

429-429: Consider adding type safety for the return value.

The code returns res directly if res.val is undefined, which could lead to inconsistent return types.

-        return res; // Return res directly if no .val
+        return []; // Return empty array if no results to maintain consistent return type

431-432: Improve error handling with more context.

When a batch fails, we're logging the error but not capturing any details about which specific keyIds failed.

-        console.error(`Batch ${batchIndex} query failed:`, error);
-        return [];
+        console.error(`Batch ${batchIndex} query failed with keyIds [${batchKeyIds.map(k => k.value).join(', ')}]:`, error);
+        return [];
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adc782a and 1fb9bdb.

📒 Files selected for processing (1)
  • internal/clickhouse/src/verifications.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Build / Build
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (3)
internal/clickhouse/src/verifications.ts (3)

403-443: Excellent implementation of batch processing to solve keyId overflow issues.

This function elegantly handles the case where a large number of keyIds are provided by:

  1. Directly using the existing querier for small batches
  2. Breaking large keyId lists into manageable chunks
  3. Processing batches in parallel using Promise.allSettled
  4. Handling errors gracefully without failing the entire operation

445-486: Well-implemented result merging function with proper handling of nullable fields.

The function correctly:

  1. Uses a Map to efficiently group by timestamp
  2. Handles potentially null/undefined values with the nullish coalescing operator
  3. Carefully sums all count metrics while preserving the data structure
  4. Returns the results in chronological order

488-522: Clean and consistent update of the exported functions.

All timeseries functions have been consistently updated to use the new batching mechanism while maintaining the same API signature, making this a non-breaking change.

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: 0

🧹 Nitpick comments (2)
apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (2)

23-27: Consider a streamlined approach to checking multiple filters.
While the current logic works, you could simplify filter checks with an array-based approach:

-    const hasKeyFilters =
-      (transformedInputs.keyIds !== null && transformedInputs.keyIds.length > 0) ||
-      (transformedInputs.names !== null && transformedInputs.names.length > 0) ||
-      (transformedInputs.identities !== null && transformedInputs.identities.length > 0);
+    const filtersList = [
+      transformedInputs.keyIds,
+      transformedInputs.names,
+      transformedInputs.identities,
+    ];
+    const hasKeyFilters = filtersList.some((arr) => arr && arr.length > 0);

29-29: Minimize complexity by removing the union type if null is never assigned.
Currently, keyIds is defined as KeysOverviewFilterUrlValue[] | null but always initialized to []. Consider standardizing to just an array:

-let keyIds: KeysOverviewFilterUrlValue[] | null = [];
+let keyIds: KeysOverviewFilterUrlValue[] = [];
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1fb9bdb and 1096a83.

📒 Files selected for processing (1)
  • apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: Test Packages / Test ./internal/hash
  • GitHub Check: Test Packages / Test ./packages/nextjs
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Build / Build
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts (6)

2-2: No concerns with the newly imported type.
This import appears correct and aligns well with usage in the key-filters logic later on.


6-6: Importing getApi and queryApiKeys is appropriate.
These new imports look consistent with the usage in this file.


12-18: Validation logic and error handling look correct.
Throwing a NOT_FOUND error if api or api.keyAuth?.id is missing is an appropriate approach to guard against invalid or unconfigured APIs.


20-20: Assignment of keyspaceId is straightforward.
No issues here; the naming and usage are clear.


54-57:

Details

✅ Verification successful

Double-check the error handling requirement for ClickHouse queries.
Previously, partial checks may have occurred on the result. If the ClickHouse library throws on error, it’s fine. Otherwise, confirm that returning the raw result aligns with your error-handling strategy.


🏁 Script executed:

#!/bin/bash
# Searching for usage of clickhouse.verifications.timeseries calls
# to confirm if there's any recommended error-checking convention.
rg -A 5 "clickhouse\.verifications\.timeseries"

Length of output: 1366


Action: Confirm ClickHouse Error-Handling Behavior

After verifying similar usage in both the apps/dashboard/lib/trpc/routers/api/keys/query-overview-timeseries/index.ts and apps/dashboard/lib/trpc/routers/api/overview/query-timeseries/index.ts files, it appears that the code consistently relies on the ClickHouse library to throw errors. In both instances, the raw result is returned without additional error-checking logic. Please confirm that this approach is in line with your overall error-handling strategy—specifically, that the library does indeed throw exceptions on errors and that no extra checks are required.


31-42:

Details

✅ Verification successful

Confirm if an empty result set should lead to an error or is acceptable.
When hasKeyFilters is true but no keys match, keyIds becomes an empty array. Depending on your business logic, this might be correct or it may require a special error.

Run this script to check how queryApiKeys is used elsewhere and see if empty results are intentionally handled:


🏁 Script executed:

#!/bin/bash
# Verifying usage of queryApiKeys throughout the codebase.
rg -A 5 "queryApiKeys"

Length of output: 4788


Clarification on Handling Empty Key Sets
Based on our review of how queryApiKeys is used throughout the codebase (e.g., in the logs and active keys timeseries endpoints), it appears that returning an empty array when no keys match is the expected and consistent behavior. There’s no evidence elsewhere in the codebase that an empty result should trigger an error. If this aligns with your business logic, then the current implementation is acceptable.

@chronark chronark enabled auto-merge March 17, 2025 14:28
@chronark chronark added this pull request to the merge queue Mar 17, 2025
Merged via the queue into main with commit 1581072 Mar 17, 2025
28 of 29 checks passed
@chronark chronark deleted the fix-overflowed-key-issue branch March 17, 2025 14:31
@coderabbitai coderabbitai bot mentioned this pull request Aug 15, 2025
18 tasks
@coderabbitai coderabbitai bot mentioned this pull request Sep 12, 2025
18 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants