Skip to content

Conversation

bmingles
Copy link
Contributor

@bmingles bmingles commented Jul 21, 2025

DH-19897: Handle missing jsapi/dh-internal.js files on core workers

I added a flag to resolve 404s as empty content instead of throwing an error. 404s were already differentiated from other errors that get retry attempts, so it was a simple change.

Testing

I tested locally by renaming jsapi/dh-internal.js in the loadModules call to jsapi/dh-internal2.js to mimick a 404. Confirmed empty content file gets created in VS Code extension.

I also tested stopping the server which produces a different error that invokes the retry mechanism instead of a 404. Worst case scenario, if we ever get out of sorts, restarting VS Code will delete the tmp download folder and retry everything again.

@bmingles bmingles requested a review from mofojed July 21, 2025 17:04
Copy link

codecov bot commented Jul 21, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 44.67%. Comparing base (5d15019) to head (b988a59).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #2501    +/-   ##
========================================
  Coverage   44.67%   44.67%            
========================================
  Files         762      762            
  Lines       42617    42617            
  Branches    10710    10906   +196     
========================================
  Hits        19038    19038            
+ Misses      23568    23522    -46     
- Partials       11       57    +46     
Flag Coverage Δ
unit 44.67% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Member

@mofojed mofojed left a comment

Choose a reason for hiding this comment

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

This is a pretty hacky solution; my only real issue is making this a breaking change, when we really should try our best not to be breaking APIs unnecessarily.
We could convert the function to take an object, but also still accept the old parameter list for example; or somehow do this so it doesn't require a breaking change... perhaps the post download transform could be used, to handle an error scenario and return content instead.

@bmingles
Copy link
Contributor Author

This is a pretty hacky solution; my only real issue is making this a breaking change, when we really should try our best not to be breaking APIs unnecessarily. We could convert the function to take an object, but also still accept the old parameter list for example; or somehow do this so it doesn't require a breaking change... perhaps the post download transform could be used, to handle an error scenario and return content instead.

@mofojed I think I can make it such that the api contract doesn't have to change loadModules at all and that it doesn't have to be responsible for providing the empty content. I should be able to isolate changes to loadDhModules.

The 1 piece in loadDhModules where I think we need to change the behavior is that we want the default behavior to be write empty content so that consumers going forward don't always have to configure this. This wouldn't change any of the function calls, but it does slightly change when errors are thrown. Not sure if this is considered a breaking change or not.

download,
storageDir,
targetModuleType,
handleErrorsInPostDownload,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mofojed This isn't my favorite, but it should get rid of the breaking change.

Alternative would be to check the number of args in the PostDownloadTransform function and if it expects 3 args assume it wants to handle errors. This may still technically be a breaking change since someone could have passed in a 3 arg function already, and this would change the behavior. This would be a crazy edge case though IMO.

Copy link
Member

Choose a reason for hiding this comment

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

Eh this is alright but the flag isn't being used correctly right now. You could just add an errorTransform specifically rather than the download transform, and use the appropriate transform for the situation.

// know whether it's present or not. Treat 404s as empty content
// to make things compatible with both configurations.
if (error instanceof HttpError && error.statusCode === 404) {
return '';
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should really be the only behavior change from the consumers perspective, and I don't think there's any real scenarios where this file would 404 when a server is up and running except our future scenario when we remove the file.

@bmingles bmingles requested a review from mofojed July 21, 2025 19:37
Comment on lines 72 to 85
if (typeof download === 'function' && handleErrorsInPostDownload === true) {
// If we are to handle errors in post download, we need to get both
// resolved and rejected Promises.
const settledResults = await Promise.allSettled(downloadPromises);

contents = settledResults.map((result, i) =>
result.status === 'fulfilled'
? // Post-download transform
download(serverPaths[i], result.value)
: // Post-download transform that also handles errors
download(serverPaths[i], '', result.reason)
);
} else {
contents = await Promise.all(downloadPromises);
Copy link
Member

Choose a reason for hiding this comment

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

You're only using the download transform if handleErrorsInPostDownload is true right now.

(serverPath, content) => {
if (serverPath === 'jsapi/dh-core.js') {
(serverPath, content, error) => {
if (serverPath === DH_CORE_MODULE) {
Copy link
Member

Choose a reason for hiding this comment

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

Should be re-throwing the error here.
Probably should just have a case for the error case originally, e.g.

if (error != null) {
  if (serverPath === DH_INTERNAL_MODULE && error instanceof HttpError && error.statusCode === 404) {
    // This is the one error we want to ignore
    return '';
  }
  throw error;
}

Then below is just replacing the content in the success cases.

download,
storageDir,
targetModuleType,
handleErrorsInPostDownload,
Copy link
Member

Choose a reason for hiding this comment

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

Eh this is alright but the flag isn't being used correctly right now. You could just add an errorTransform specifically rather than the download transform, and use the appropriate transform for the situation.

@bmingles bmingles requested a review from mofojed July 22, 2025 16:11
@bmingles bmingles merged commit 7ecb9ac into deephaven:main Jul 22, 2025
11 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Jul 22, 2025
@bmingles bmingles deleted the DH-19897_optional-dh-internal branch July 22, 2025 16:56
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants