prismicio / prismic-client

The official JavaScript + TypeScript client library for Prismic
https://prismic.io/docs/technical-reference/prismicio-client
Apache License 2.0
168 stars 60 forks source link

Helper functions don't return a response status code. #155

Closed luismiddleton closed 2 years ago

luismiddleton commented 3 years ago

Hey team,

After trawling through your documentation for globals, I doesn't seem that any of the helper functions (e.g. getByUID, getByID) return a status code with Promise<Document>

So it's difficult to distinguish when we have a Document that returns valid data:

e.g.

{
    id: string;
    uid?: string;
    url?: string;
    data: [ title: "Title", description: "Description" ];
}

and a Document that contains no data:

{
    id: string;
    uid?: string;
    url?: string;
    data: null;
}

I was under the presumption that the callback function can return a Response, but seems to return undefined every-time.

How can we better distinguish a response status, without having to resort to conditional or ternary operator for data like below ?

const doc = await Client(req).getByUID('example-type', '12345', {});

const statusCode = doc?.data ? 200 : 404;
lihbr commented 3 years ago

Hey @luismiddleton, thanks for asking!

That's an interesting problem you're bringing here, ran some tests on my side, here are the results:

// index.js
const Prismic = require("@prismicio/client");

(async () => {
  const client = await Prismic.client("https://200629-sms-hoy.prismic.io/api/v2");

  const home = await client.getByUID("page", "home"); // exist, filled
  console.log({ home }); // { id, uid, type, ..., data}

  const fourofour = await client.getByUID("page", "homee"); // doesn't exist
  console.log({ fourofour }); // undefined

  const empty = await client.getByUID("page", "empty"); // exists, but empty
  console.log({ empty }); // { id, uid, type, ..., data}

  const empty2 = await client.getSingle("empty"); // exists, but empty
  console.log({ empty2 }); // { id, uid, type, ..., data}
})();

So it appears that real 404s just return undefined, therefore checking for that should be enough to discern a 404 from a 200? I'm adding your feedback to our board although so we can consider being more explicit here~

Cheers!

lihbr commented 3 years ago

@angeloashmore can you confirm behavior is an expected one on this one with v6? Closing it if yes ☺️

lihbr commented 2 years ago

@angeloashmore can you just double check that behavior is a bit more expected on v6? 🙏

angeloashmore commented 2 years ago

@lihbr @luismiddleton So sorry that I missed this question!

In v6, documents that do not exist will throw a NotFoundError. This is detected by checking for a 404 status code (see these lines). Different errors are thrown for other status codes like 400, 401, or 403.

All errors extend from PrismicError. This allows you to have a catch-all if-statement if you want to only intercept Prismic API errors.

You could do something like the following to safely query for a document:

import * as prismic from "@prismicio/client";

const endpoint = prismic.getEndpoint("my-repo-name");
const client = prismic.createClient(endpoint);

let doc;

try {
    doc = await client.getByUID("page", "home");
} catch (error) {
    if (error instanceof prismic.NotFoundError) {
        // You can handle a "not found" query here.
        console.error('The "home" page was not found.');
    } else {
        // You can handle any other error here.
        console.error(error);
    }
}

// `doc` is now a Page document or undefined if it did not exist