and no object exists with that exact id the error is not very explicit or useful.
I have a strong preference for explicit error return objects in GraphQL to handle this kind of thing, but the Dato GraphQL is probably not going to adapt those any time soon. So I ask generally, whatās the best way to handle ānot foundā scenarios like this? Currently Iām running a string comparison on the error message itself, but it feels wrong.
Or if you need a more explicit āthis entry is goodā check, you can validate post._status==='published' and/or post._isValid===true, perhaps?
Iām not sure of your use case here (why would it ever be looking up a nonexistent ID to begin with?), but if you can provide an example, maybe we can help think of something more suitable?
Thatās interesting, Iām definitely not getting null, that would actually be a better scenario. I think Iām hitting some kind of regex checking for the old and new id formats. If you try adding a dash or something to the id to make it invalid looking, what happens?
The reason Iām getting non-existing idās is just because of some bot traffic I think. Iām just seeing this come up in my logs and donāt want a 500 error but a nice 404.
Forgot to add, this is the error message Iām getting and checking for:
Variable $id of type ItemId! was provided invalid value
I see, thank you for explaining! That does indeed happen if you provide altogether invalid IDs (like if a bot were just scanning for them and making up IDs).
First, I should probably point out that itās not a great idea to have your page routing directly tied to API lookups, if for no other reason than that this would make for easy denial-of-service attacks from any bot going to your pages (existent or not). You would then have to pay for all their pointless API calls It would be safer to route only to pages (IDs) you know youāve created and to 404 or redirect other ones by default, unless you are specifically trying to dynamically generate pages for SEO or such.
That will test the ID for validity so you donāt pass it on to the API if itās junk.
(Edit: The package has since been updated. The below comment is no longer relevant.)
(Outdated, please ignore): Click to expand: Only relevant if your Dato project still has number-only IDs
Side note: If your Dato project is really old, and not using alphanumeric IDs yet (i.e., it still has integer IDs from our past), you can also allow through 6-byte integer IDs (i.e., ints <= 281474976710655). That check is NOT present in the isValidId() option but IS in the GraphQL layer, which is why integer IDs still work there. Newer projects donāt have to worry about this at all.
That helps - and thanks for including that note on integer IDās - we do indeed have a lot of those. SEO is very important for us so we are just rendering everything dynamically. This check will really help prevent attacks that rack up our billing.
When looking at that code for isValidId, I notice that the first lines are:
// For backward compatibility, first check to see if this is an older-style integer ID formerly used by Dato
if (/^\d+$/.test(id)) {
const intId = BigInt(id);
const maxDatoIntegerId = 281474976710655; // Max 6-byte/48-bit unsigned int
return intId <= maxDatoIntegerId;
}
This directly contradicts your comment that legacy ID checking isnāt supported. Unless Iām misunderstanding something ā¦
Oh, hah, that was fast! I made a PR for that because of your post here. I didnāt expect it to get merged in so soon (it usually takes a few days, but our devs were on it this time!).
That means you can just go ahead and use that code then. Sorry for the confusion. It wasnāt there yet when I first replied
Good call. Iāve asked for a version release and will let you know once itās up. (If itās time sensitive, you could also copy that code or fork the repo to get it working sooner).