Skip to content

Conversation

@valkirilov
Copy link
Member

@valkirilov valkirilov commented Nov 28, 2025

What

Fixes the issue where users see raw JavaScript errors like "Cannot read properties of null (reading 'split')" when adding cloud databases with invalid endpoints. Now returns user-friendly error messages instead.

Testing

Prerequisites: You need a Redis Cloud account with a PRO-tier subscription database with a disabled public endpoint.

  1. Open Redis Insight and login to Redis Cloud (top right corner)
  2. From the top right corner, click on your avatar and then click "Import Cloud Databases"
  3. Select your subscription from the "Redis Cloud Subscriptions" screen
  4. Select your databases from the "Redis Cloud Databases" screen

You'll be redirected to the "Redis Enterprise Databases Added" screen, once the import is done. Observe the errors in the Results column.

Before After
image image

Note

Introduce CloudDatabaseEndpointInvalid error (code 11_116) and use it to validate missing publicEndpoint across cloud import/create flows, with tests and docs updates.

  • Backend/API:
    • Custom Error: Add CloudDatabaseEndpointInvalidException with message CLOUD_DATABASE_ENDPOINT_INVALID and code CustomErrorCodes.CloudDatabaseEndpointInvalid.
    • Usage:
      • Validate publicEndpoint in cloud-autodiscovery.service and return structured failure when missing.
      • Throw in jobs create-free-database.cloud-job and import-free-database.cloud-job when publicEndpoint is absent.
    • Constants: Add error code 11_116 in api/src/constants/custom-error-codes.ts; add message in api/src/constants/error-messages.ts.
    • Exports: Re-export new exception in cloud/job/exceptions/index.ts.
  • Tests:
    • Add parameterized cases (it.each) for null/undefined publicEndpoint in cloud-autodiscovery.service.spec.ts.
  • UI:
    • Mirror error code CloudDatabaseEndpointInvalid = 11_116 in ui/src/constants/customErrorCodes.ts.
  • Docs/Guides:
    • Backend rules: add guidance and example for custom exceptions.
    • Commits rules: note to keep commit bodies concise.
    • Testing rules: add it.each usage guidance.

Written by Cursor Bugbot for commit c386bae. This will update automatically on new commits. Configure here.

Validate publicEndpoint before calling split() to prevent null reference errors.
Return user-friendly error messages instead of raw JavaScript errors.

References: #RI-7778
- Introduced a section on custom exceptions, emphasizing their benefits for consistent error handling.
- Added examples for creating custom exceptions in TypeScript.
- Included a new section on parameterized tests using `it.each`, highlighting its advantages for maintainability and readability.
@github-actions
Copy link
Contributor

github-actions bot commented Nov 28, 2025

Code Coverage - Integration Tests

Status Category Percentage Covered / Total
🟢 Statements 81.63% 16290/19954
🟡 Branches 64.57% 7347/11377
🟡 Functions 70.61% 2285/3236
🟢 Lines 81.28% 15327/18857

@github-actions
Copy link
Contributor

github-actions bot commented Nov 28, 2025

Code Coverage - Backend unit tests

St.
Category Percentage Covered / Total
🟢 Statements 92.3% 13889/15048
🟡 Branches 74.02% 4193/5665
🟢 Functions 85.81% 2135/2488
🟢 Lines 92.1% 13277/14416

Test suite run success

2967 tests passing in 287 suites.

Report generated by 🧪jest coverage report action from c386bae

@valkirilov valkirilov marked this pull request as ready for review November 28, 2025 12:50
@valkirilov valkirilov self-assigned this Nov 28, 2025
publicEndpoint: string | null | undefined,
): boolean {
return (
!!publicEndpoint && !!publicEndpoint.trim() && publicEndpoint.includes(':')
Copy link
Collaborator

Choose a reason for hiding this comment

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

is this the best way to check it or there can be a regex with more rules?

Copy link
Member Author

@valkirilov valkirilov Nov 28, 2025

Choose a reason for hiding this comment

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

Actually, all we care about is whether there is a value for the publicEndpoint, but since we split it later in the code by :, the AI considered it makes sense to check it here as well.

For sure, we can make the validation smarter, but I don't have the requirements for it, so here we're just improvising.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would say we just need to check if we have not empty string. It should be enough.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, done. I have simplified the validation so we check only whether the publicEndpoint is present 👍

Comment on lines +170 to +173
message,
statusCode: HttpStatus.BAD_REQUEST,
error: 'FeatureInvalid',
errorCode: CustomErrorCodes.FeatureInvalid,
Copy link
Collaborator

Choose a reason for hiding this comment

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

does it make sense to enforce that these fields are provided for all exceptions (e.g. extract and implement a common interface)? Currently it's typed as Record<string, any> and if we have a common interface, we can have more predictive api responses

Copy link
Member Author

Choose a reason for hiding this comment

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

This is the current pattern, so I just plugged into it.

What you suggest sounds reasonable to me, but I believe @ArtemHoruzhenko can advise on architectural changes like that.

CLOUD_DATABASE_IMPORT_FORBIDDEN:
'Adding your Redis Cloud database to Redis Insight is disabled due to a setting restricting database connection management.',
CLOUD_DATABASE_ENDPOINT_INVALID:
'Database endpoint is not available or not fully provisioned yet.',
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we change the message?
I would say that we must say something like: "Public endpoint is disabled for this database"

Copy link
Member Author

Choose a reason for hiding this comment

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

Of course, we can put whatever we want.

publicEndpoint: string | null | undefined,
): boolean {
return (
!!publicEndpoint && !!publicEndpoint.trim() && publicEndpoint.includes(':')
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would say we just need to check if we have not empty string. It should be enough.

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.

4 participants