4

App builds fine locally and works on local production server + development server. The api used to fetch data is working fine.

Code which is producing the error

export const getStaticProps = async () => {
    const resp = await fetch(
        'https://cdn-api.co-vin.in/api/v2/admin/location/states',
        {
            headers: {
                'User-Agent': '*',
            }, //this is required by api provider
        }
    );
    const data = await resp.json();
    //console.log('states in getStaticProps : ', data);

    return { props: { data: JSON.parse(JSON.stringify(data)) } };
};  

const Ninjas = ({ data: { states } }) => {
    console.log('Ninjas : ', states);
    return (
        <>
            <Head>
                <title> Listing</title>
            </Head>
            <div>
                {states.map((ei) => (
                    <div key={ei.state_id}>
                        <a className={styles.single}>
                            <h3>{ei.state_name}</h3>
                        </a>
                    </div>
                ))}
            </div>
        </>
    );
};

export default Ninjas;

Following is the vercel log.

20:17:40.644    Cloning github.com/user-name/co2-app (Branch: main, Commit: 8ab0e48)
20:17:41.349    Cloning completed: 704.592ms
20:17:41.374    Analyzing source code...
20:17:42.573    Installing build runtime...
20:17:45.235    Build runtime installed: 2.662s
20:17:48.104    Looking up build cache...
20:17:48.453    Build cache not found
20:17:49.697    Installing dependencies...
20:18:04.559    > ejs@2.7.4 postinstall /vercel/path0/node_modules/ejs
20:18:04.559    > node ./postinstall.js
20:18:05.113    npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules/fsevents):
20:18:05.113    npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})
20:18:05.116    added 600 packages from 352 contributors in 14.87s
20:18:05.426    64 packages are looking for funding
20:18:05.426      run `npm fund` for details
20:18:05.492    Detected Next.js version: 10.2.0
20:18:05.492    Running "npm run build"
20:18:05.756    > we2-cowax@0.1.0 build /vercel/path0
20:18:05.757    > next build
20:18:07.292    info  - Using webpack 4. Reason: custom webpack configuration in next.config.js https://nextjs.org/docs/messages/webpack5
20:18:08.224    info  - Checking validity of types...
20:18:08.244    Attention: Next.js now collects completely anonymous telemetry regarding usage.
20:18:08.245    This information is used to shape Next.js' roadmap and prioritize features.
20:18:08.245    You can learn more, including how to opt-out if you'd not like to participate in this anonymous program, by visiting the following URL:
20:18:08.245    https://nextjs.org/telemetry
20:18:08.326    info  - Creating an optimized production build...
20:18:08.748    > [PWA] Compile client (static)
20:18:08.748    > [PWA] Auto register service worker with: /vercel/path0/node_modules/next-pwa/register.js
20:18:08.750    > [PWA] Service worker: /vercel/path0/public/service-worker.js
20:18:08.750    > [PWA]   url: /service-worker.js
20:18:08.750    > [PWA]   scope: /
20:18:08.860    > [PWA] Compile server
20:18:25.603    info  - Compiled successfully
20:18:25.604    info  - Collecting page data...
20:18:26.366    info  - Generating static pages (0/3)
20:18:26.918    error :  invalid json response body at https://cdn-api.co-vin.in/api/v2/admin/location/states reason: Unexpected token < in JSON at position 0
20:18:26.919    Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
20:18:26.919    Error: Error serializing props returned from `getStaticProps` in "/".
20:18:26.919    Reason: Props must be returned as a plain object from getStaticProps: `{ props: { ... } }`.
20:18:26.919        at isSerializableProps (/vercel/path0/node_modules/next/dist/lib/is-serializable-props.js:1:462)
20:18:26.919        at renderToHTML (/vercel/path0/node_modules/next/dist/next-server/server/render.js:30:1730)
20:18:26.919        at processTicksAndRejections (internal/process/task_queues.js:93:5)
20:18:26.919        at async /vercel/path0/node_modules/next/dist/export/worker.js:26:6
20:18:26.919        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.920    info  - Generating static pages (3/3)
20:18:26.921    > Build error occurred
20:18:26.926    Error: Export encountered errors on following paths:
20:18:26.926        /
20:18:26.926        at /vercel/path0/node_modules/next/dist/export/index.js:31:1106
20:18:26.926        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.927        at async /vercel/path0/node_modules/next/dist/build/index.js:43:49
20:18:26.927        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.927        at async /vercel/path0/node_modules/next/dist/build/index.js:25:1475
20:18:26.927        at async Span.traceAsyncFn (/vercel/path0/node_modules/next/dist/telemetry/trace/trace.js:6:584)
20:18:26.954    npm ERR! code ELIFECYCLE
20:18:26.954    npm ERR! errno 1
20:18:26.958    npm ERR! co2-app@0.1.0 build: `next build`
20:18:26.958    npm ERR! Exit status 1
20:18:26.958    npm ERR! 
20:18:26.959    npm ERR! Failed at the we2-cowax@0.1.0 build script.
20:18:26.959    npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
20:18:26.968    npm ERR! A complete log of this run can be found in:
20:18:26.968    npm ERR!     /vercel/.npm/_logs/2021-05-17T14_48_26_959Z-debug.log
20:18:26.982    Error: Command "npm run build" exited with 1

I am using next-pwa for PWA functionality and hence custom webpack version

Have delete the app at Vercel and re-deploy, even removed the cache build but still can't resolve the error

Speedy11
  • 197
  • 1
  • 5
  • 11

1 Answers1

2

Problem

The API is returning a 403 forbidden error:

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>

<HEAD>
    <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
    <TITLE>ERROR: The request could not be satisfied</TITLE>
</HEAD>

<BODY>
    <H1>403 ERROR</H1>
    <H2>The request could not be satisfied.</H2>
    <HR noshade size="1px">
    Request blocked.
    We can't connect to the server for this app or website at this time. There might be too much traffic or a
    configuration error. Try again later, or contact the app or website owner.
    <BR clear="all">
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
    <BR clear="all">
    <HR noshade size="1px">
    <PRE>
Generated by cloudfront (CloudFront)
Request ID: BqNxi8x1nTA3YKM_N3JSCyjGVDYnMUDNFvS_HgJGB8glTFr1uVh6Ug==
</PRE>
    <ADDRESS>
    </ADDRESS>
</BODY>

</HTML>

which is not then being handled correctly by your getStaticProps function (in this case, an invalid response can't be turned into JSON; also, your User-Agent is not valid):

export const getStaticProps = async () => {
    const resp = await fetch(
        'https://cdn-api.co-vin.in/api/v2/admin/location/states',
        {
            headers: {
                'User-Agent': '*',
            }, //this is required by api provider
        }
    );

    // this throws an error because you can't turn
    // the invalid server response into JSON
    const data = await resp.json();

    return { props: { data: JSON.parse(JSON.stringify(data)) } };
};

which is also not being handled correctly by your Ninjas component -- states would be undefined because the server doesn't respond with valid data and you can't map an undefined variable. Instead you should check that states is a non-empty Array before mapping over it by either using lodash's isEmpty: !isEmpty(states) && states.map(...) or by checking that it's defined and has length: Array.isArray(states) && states.length > 0 && states.map(...).

Solution

import Head from "next/head";
import isEmpty from "lodash.isempty";

export const getStaticProps = async () => {
  let data = [];
  let error = "";
  try {
    const res = await fetch(
      "https://cdn-api.co-vin.in/api/v2/admin/location/states",
      {
        method: "GET",
        headers: {
          // update with your user-agent
          "User-Agent":
            "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36",
          Accept: "application/json; charset=UTF-8",
        },
      }
    );

    if (res.status !== 200)
      throw String(`Invalid server response: ${res.status} ${res.statusText}`);

    data = await res.json();

    if (isEmpty(data)) throw String("No data was found!");

    data = JSON.parse(JSON.stringify(data));
  } catch (e) {
    error = e.toString();
  }

  return {
    props: {
      data,
      error,
    },
  };
};

const Ninjas = ({ data, error }) => (
  <>
    <Head>
      <title> Listing</title>
    </Head>
    <div>
      {error && <p style={{ color: "red" }}>{error}</p>}
      {!isEmpty(data) && !isEmpty(data.states) &&
        data.states.map((ei) => (
          <div key={ei.state_id}>
            <a className={styles.single}>
              <h3>{ei.state_name}</h3>
            </a>
          </div>
        ))}
    </div>
  </>
);

export default Ninjas;
Matt Carlotta
  • 18,972
  • 4
  • 39
  • 51
  • thank for your time and insights. this does work but again only offline. API returns with the data only in dev mode but fails when deployed on Vercel. Any particular reason why an API would fail when deployed? – Speedy11 May 23 '21 at 13:05
  • 1
    Hard to say without a working API in development (for me). But the problem isn’t with Vercel, but with the API response. Also, if it fails, it should now be showing you why. If I had to guess, it’s blocking the Vercel domain name from making requests to the API. – Matt Carlotta May 23 '21 at 14:26
  • the url to which I am making the req is in the code above. Yes the prob is with the resp from the server, the server is not responding with the data either on Vercel or Heroku. any specific header I should be looking for in the server's response? to be clear as whats the server's requirements. Thank you – Speedy11 May 24 '21 at 06:22
  • this is link to the api service provider -> https://apisetu.gov.in/public/api/cowin – Speedy11 May 24 '21 at 06:27
  • 1
    My guess is that the API is region locked to India. Therefore, any requests not coming from an `.in` domain or a known Indian IP address are rejected. Since I don't have access to an Indian VPN server it's not possible for me to test. – Matt Carlotta May 24 '21 at 07:32
  • Thank you very much for your time and assistance . Take care – Speedy11 May 24 '21 at 07:42