Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Filter invalid values in getIds #979

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

duncanbeevers
Copy link
Contributor

@duncanbeevers duncanbeevers commented Dec 12, 2024

🏋️ getIds robustness

getIds is a useful utility function, but it accepts a limited subset of the valid ObjectId constructor argument types, and throws when presented with invalid input.

It's not straight-forward to filter inputs to be valid constructor arguments; in some codebases we maintain bespoke utilities for performing these checks (eg; isValidObjectId).

Unfortunately, the canonical validation for whether one of these arguments is a valid argument to the ObjectId constructor is cooked-in to the constructor itself.

Therefore, rather than re-implementing this logic (or trying to get it extracted and exposed upstream), I updated the getIds implementation to rely on the constructor logic through try/catch, and to discard invalid elements.

🐤 Backwards-Compatibility

Per discussion, this is going to be a breaking change.

In order to keep the change backwards-compatible, I gated the filtering functionality behind a filterInvalid option, passed to getIds. If we were okay with making a breaking release, I think this would be much nicer as the default behavior.

🔧 Changes

I updated getAll (🟦) and its specs (🟡) in a few ways.

  • 🟦 make getAll accept an Iterable<ObjectIdConstructorParameter>, widening acceptable input types
  • 🟦 add optional GetIdsOptions argument to getIds, with optional filterInvalid boolean member
  • 🟦 change getIds inner map to flatMap, to allow single-pass filtering
  • 🟦 add try/catch to getIds inner flatMap, to rely on ObjectId constructor validation behavior
  • 🟦 add error re-throw to getIds inner flatMap, gated on filterInvalid option
  • 🟡 make expected result part of each test case
  • 🟡 introduce variety between test case values / fixtures
  • 🟡 add invariant check that expected result length must be less-than-or-equal-to input length
  • 🟡 add test cases for Uint8Array arguments
  • 🟡 add test cases for invalid input
  • 🟡 add test case for invalid input with no filterInvalid option

@ejmartin504
Copy link
Collaborator

ejmartin504 commented Dec 12, 2024

If we were okay with making a breaking release, I think this would be much nicer as the default behavior.

I would 100% prefer this.

I know I'm always the one who says "is this really a breaking change" -- and I must say this is an interesting example! After all, this should fix existing uses, rather than break them... right? It's hard to imagine code depending on invalid input to this function throwing 🤷

@avaly
Copy link
Collaborator

avaly commented Dec 13, 2024

I agree with making this a breaking change. Let's remove the options argument.

@duncanbeevers
Copy link
Contributor Author

Is it worth it to extract the validation functionality from bson to avoid the try/catch, or ship with this implementation?

duncanbeevers added a commit to duncanbeevers/papr that referenced this pull request Dec 13, 2024
Copy link
Collaborator

@avaly avaly left a comment

Choose a reason for hiding this comment

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

We can ship this as is, but let's mark the commit as a breaking change.

@duncanbeevers duncanbeevers force-pushed the feat/validating-getids branch from b98bfd6 to d6bf05f Compare January 14, 2025 15:47
@duncanbeevers
Copy link
Contributor Author

duncanbeevers commented Jan 14, 2025

I removed the filterInvalid option and made the filtering the default behavior. Let me know if there's more I need to do in order to mark this as a breaking change.

I also squashed this all down to a single commit because it was terrible fixing each of the conflicts that arose in the test file; easier to just fix everything all at once.

@duncanbeevers duncanbeevers requested a review from avaly January 15, 2025 15:07
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.

3 participants