react-dropzone: pass rejection reason to onDropRejected callback

Do you want to request a feature or report a bug?

  • I found a bug
  • I want to propose a feature

I’d like to get a reason for rejection in the onDropRejected callback currently I only get the file that was rejected. There was a request opened up previously #735, but it was closed. I am not sure why because the request was valid one and the response didn’t really help the reporter.

From what I can see there can be 3 reasons:

  • you dragged multiple files to multiple={false} dropzone
  • bad mime type
  • file too big

Sure I can have a series of if statements in my callback to recognize what was the reason for rejection, but why do this work again when react-dropzone already done it?

Also it would be nice to have default error messages for those 3 scenarios, I’d propose:

  • File ${file.name} is not supported
  • Only accepts a single file
  • File ${file.name} is ${bytes(file.size)}, the upper limit for file size is ${bytes(maxFileSize)}

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 8
  • Comments: 20 (1 by maintainers)

Most upvoted comments

Thanks for looking into it @rolandjitsu

Any implementation for this will be step forward in my opinion - but I have one suggestion - maybe it would be better to keep the error/validation as a string code that can be easily compared by a developer if he wants to show their own error messages?

I mean something like I’ve previously suggested: file-invalid-type, file-too-large, file-too-small, file-overflow/file-excessive, etc.

Or maybe even combined approach? Like this:

interface FileError extends Error {
  message: string; // e.g. 'File is larger than {maxSize}', 'File type does not meet {accept} criteria', etc.
  code: string; // e.g.  'file-too-large' 
  file: File;
}

HEllo. Any news about PR?

This is the only thing that confused me in this otherwise excellent component. I was sure that onDropRejected will provide the reasons.

Instead making users figure rejection reasons on their own, showing specific reasons to them why their file(s) were rejected is in my opinion important consideration for better user experience .

And I think this should be done in the scope of this component instead on the developer side.

@rolandjitsu could you provide more insight why pulling additional dependencies to detect the specific reasons is needed? From what I understand the current source code already has to have logic in place to know when to reject the file(s). I can see there are checks already like fileAccepted (for mime checking) or fileMatchSize. I’d say there is no need to add additional dependencies because the functionality is already here.

I don’t think implementing this feature would add a lot extra size to this library.


As for solution for this problem, the best I can think of right now is to change the structure of rejectedFiles to something like this (and bump the major version of package as this would be breaking change):

rejectedFiles: [
  {
    file: file,
    reasons: <reasons array>,
  }
]

The reasons could be strings like file-invalid-type, file-too-large, file-too-small, file-overflow/file-excessive, etc. Those reason codes could be then used by developer to show more ‘pretty’ messages to users.

Hello, I have been working on this. Just need to see finish testing and then should be able to submit a pull request.

is it possible to customize the rejection message?

🎉 This issue has been resolved in version 11.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@rolandjitsu Thanks for the reply. My particular error was a special situation. Chrome had stopped working properly, the developer tab froze but the browser didn’t, and something was causing the react-dropzone code to fail. The only fix was to close the tab and reload the page, then everything started working again.

I still believe that this ticket is necessary as I could have understood that it was failing for at least one of those 3 reasons, or perhaps a 4th unknown reason (“Chrome lost its mind”). Thanks @nylon22 for working on this!

@ducdev unless someone else is working on this, there is nothing new.

@ajbogh this feature won’t help you debug errors of that nature. This lib rejects files for 3 reasons (that I can remember):

  • file size (controller by minSize, maxSize props)
  • file count (controller by multiple prop)
  • file type (controller by accept prop)

So if your files stop being accepted, I’d start checking for those. Do note that the file type is handled by the attr-accept lib and it has some known limitations.

@nylon22 thanks for picking up on this. I definitely don’t have the time to work on this anytime soon.

Did not have time to work on this, but it’s still a valid issue.

@DominikSerafin I won’t have time to work on this, so feel free to make a PR if you still think this feature is essential.

Instead making users figure rejection reasons on their own, showing specific reasons to them why their file(s) were rejected is in my opinion important consideration for better user experience.

It wasn’t necessary to change the signature of the onDrop callback because there are only a few cases in which files are rejected (file size, file count or file type) and users could have easily accounted for that in their own code.

And I think this should be done in the scope of this component instead on the developer side.

We want to keep this lib as simple as possible, hence why I’m a bit reluctant to add support for this.

@rolandjitsu could you provide more insight why pulling additional dependencies to detect the specific reasons is needed? From what I understand the current source code already has to have logic in place to know when to reject the file(s). I can see there are checks already like fileAccepted (for mime checking) or fileMatchSize. I’d say there is no need to add additional dependencies because the functionality is already here.

I haven’t given to much thought into this matter, so I cannot say with absolute confidence whether we need or not more dependencies. It could be as simple as changing the signature of the onDrop and onDropRejected callbacks.

I don’t think implementing this feature would add a lot extra size to this library.

Probably not.


I think a better signature for onDrop/onDropRejected would be:

onDrop: (files: File[], error: null | Error | Array<FileError>, event: Event): void;
onDropRejected: (error: Error | Array<FileError>, event: Event): void;

// A simple Error should suffice when {multiple} is false and the user dropped more than one file

interface FileError extends Error {
  message: string; // e.g. 'File is larger than {maxSize}', 'File type does not meet {accept} criteria', etc.
  file: File;
}

I might have some time next week(end) to give this a shot.

@capaj you’re welcome to make a PR.

But it’s just easier to let the user know that the file(s) was rejected because of one of those 3 reasons and then the user would have to ensure that the requirements are met. We also don’t want to pull in more dependencies (bytes).

Otherwise you have to manage the rejection reasons as there might be multiple for one file (too large + wrong mime type, etc.) and that just adds complexity.