Skip to content

Wrap errors thrown in user callbacks with descriptive messages#860

Open
vikas90244 wants to merge 3 commits into
tus:mainfrom
vikas90244:fix/callback-error-wrapping
Open

Wrap errors thrown in user callbacks with descriptive messages#860
vikas90244 wants to merge 3 commits into
tus:mainfrom
vikas90244:fix/callback-error-wrapping

Conversation

@vikas90244

Copy link
Copy Markdown

Fixes #294

When a user's callback (onProgress, onError, onChunkComplete, onBeforeRequest, onAfterResponse, onShouldRetry) throws an error, the error message now clearly indicates which callback caused it instead of appearing as an internal tus error.

@Acconut Acconut left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thank you very much for working on this improvement! I have two minor comments, but otherwise this looks good :)

Comment thread lib/upload.ts
this.options.onError(err)
} catch (callbackErr) {
const causeMsg = callbackErr instanceof Error ? callbackErr.message : String(callbackErr)
throw new Error(`tus: error thrown in 'onError' callback: ${causeMsg}`)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe we can set the cause property to expose the original error to the caller.

Suggested change
throw new Error(`tus: error thrown in 'onError' callback: ${causeMsg}`)
throw new Error(`tus: error thrown in 'onError' callback: ${causeMsg}`, { cause: callbackErr })

@vikas90244 vikas90244 Apr 13, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the suggestions!

I tried using { cause: callbackErr } in the Error constructor but it results in "Expected 0-1 arguments, but got 2" since ErrorOptions is not available with the current ES2018 target.

As an alternative I considered manually assigning wrappedErr.cause = callbackErr but TypeScript also rejects this without updating the lib compiler option.
For now I've kept the implementation without .cause, the original error message is already included in the wrapping message string via causeMsg, so the information is still visible to the caller. Happy to revisit if you have a preferred approach.

Comment thread lib/upload.ts
this.options.onError(err)
} catch (callbackErr) {
const causeMsg = callbackErr instanceof Error ? callbackErr.message : String(callbackErr)
throw new Error(`tus: error thrown in 'onError' callback: ${causeMsg}`)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is it possible to add a test case for this? So we know that errors from callbacks are properly caught, wrapped and don't send the upload logic into a retry loop.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

working on it.

@vikas90244 vikas90244 requested a review from Acconut April 15, 2026 17:12
@vikas90244

Copy link
Copy Markdown
Author

Hi @Acconut , just a gentle bump on this PR when you get a chance. Thanks!

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.

Improve error message when error occurs in user's callback

2 participants