Next.js Discord

Discord Forum

prevent ioredis on next/api to fail?

Unanswered
Giant wood wasp posted this in #help-forum
Open in Discord
Giant wood waspOP
hello, it seems if my redis url or connection fail then the whole app will crash on production.
for some reason i already try to validate the redis first, if it's not good then the api will proceed without redis.
but still somehow crash on production if redis failed

17 Replies

Giant wood waspOP
for example this is the code of api/token-price

...

require("dotenv").config();

const CACHE_NAME = "data-tokenprice";

export default async function loadDataHandler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  try {
    let redisError = false;

    // Validate Redis connection with a timeout
    try {
      await Promise.race([
        redis.ping(),
        new Promise((_, reject) => {
          setTimeout(() => reject(new Error("Redis connection timeout")), 5000); // 5 seconds timeout
        }),
      ]);
    } catch (error) {
      console.error("Redis ping error:", error);
      redisError = true;
    }

    // Check if the data is present in Redis cache
    const cachedData = redisError ? null : await redis.get(CACHE_NAME);
    if (cachedData) {
      return res
        .setHeader("Cache-Control", "s-maxage=3600")
        .json(JSON.parse(cachedData));
    }

    // If the data is not cached or Redis ping failed, fetch it from BigQuery
    const bigquery = new BigQuery({
      projectId: "annular-moon-361814",
      credentials: {
        private_key: process.env.GBQ_PRIVATE_KEY,
        client_email: process.env.GBQ_EMAIL_CLIENT,
      },
    });

    const startDate = new Date();
    startDate.setDate(startDate.getDate() - 1); // Subtract 1 day from the current date

    const query = `SELECT * FROM annular-moon-361814.RAW_data.CRYPTO_prices_hourly WHERE timestamp >= TIMESTAMP("${startDate.toISOString()}")`;

    const options = {
      query: query,
    };

    const [rows] = await bigquery.query(options);

    if (!redisError) {
      // Cache the fetched data in Redis for 1 hour
      await redis.set(CACHE_NAME, JSON.stringify(rows), "EX", 3600);
    }

    return res.setHeader("Cache-Control", "s-maxage=3600").json(rows);
  } catch (error) {
    console.error("Error loading table:", error);
    return res.status(500).json({ error: "Error loading data" });
  }
}
it should validate first but on production seems not working and still continue to give 500 response because of the ioredis connection.
@Giant wood wasp you mean GCP redis? not KV or Upstash Redis? plus where do you host a Next.js, GCP or Vercel?
@tafutada777 <@656543429718704128> you mean GCP redis? not KV or Upstash Redis? plus where do you host a Next.js, GCP or Vercel?
Giant wood waspOP
i host it on vercel and digitalocean
i use google big query and ioredis
import { BigQuery } from "@google-cloud/bigquery";
import Redis from "ioredis";


it is weird, it's on-off working and sometimes failure. but failure 500 api will crash whole site

so now i setup another api route without redis.
1. api/token-price has redis + big query
2. api/test-gbq has only big query run

both has same query on GBQ

but now the api/token-price is working and yet the api/test-gbq has problem on production.
but on localhost both are working


this is the server function:
Error loading table: Error: error:1E08010C:DECODER routines::unsupported
    at Sign.sign (node:internal/crypto/sig:131:29)
    at Object.sign (/var/task/node_modules/jwa/index.js:152:45)
    at Object.jwsSign [as sign] (/var/task/node_modules/jws/lib/sign-stream.js:32:24)
    at GoogleToken.requestToken (/var/task/node_modules/gtoken/build/src/index.js:232:31)
    at GoogleToken.getTokenAsyncInner (/var/task/node_modules/gtoken/build/src/index.js:166:21)
    at GoogleToken.getTokenAsync (/var/task/node_modules/gtoken/build/src/index.js:145:55)
    at GoogleToken.getToken (/var/task/node_modules/gtoken/build/src/index.js:97:21)
    at JWT.refreshTokenNoCache (/var/task/node_modules/google-auth-library/build/src/auth/jwtclient.js:172:36)
    at JWT.refreshToken (/var/task/node_modules/google-auth-library/build/src/auth/oauth2client.js:153:24)
    at JWT.getRequestMetadataAsync (/var/task/node_modules/google-auth-library/build/src/auth/oauth2client.js:298:28) {
  library: 'DECODER routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_UNSUPPORTED'
}


sometimes all functions encountered all of those.
no idea what's the exact issue, is it vercel, the functions, my gbq, or my redis url. i deploy on digital ocean but result are same.

what annoying is this issue crash my whole site just because of 1 next/api return 500 and yet they are working perfectly on production.
what do you mean by crash? technically crash means Node.js process exits, so the web site get unreachable. (Vercel uses AWS lambda so it won't happen)
just returning 500 means app errors, we do not say crash.
and do you use Vercel KV redis?
Giant wood waspOP
https://discord.com/channels/752553802359505017/752647196419031042/1123553993340244008
https://media.discordapp.net/attachments/752647196419031042/1123553993071792158/Screenshot_2023-06-28_at_5.01.20_PM.png?width=342&height=129

this is the crash i mentioned, but why 1 next/api failed will corrupt the whole app.

no, i already have the existing redis cloud url deployed on digitalocean
import Redis from "ioredis";
require("dotenv").config();

export const redis = new Redis(process.env.REDISCLOUD_URL);


simply setup like that, and i did explained on above that i created 1 more next/api without redis and only gbq,
and that's the only one who failed 500 while on localhost is working.
so it might be not the redis problem,

my guess is connection between google apis and nextjs api is somehow create this problem.
the google apis has weird connection, on default setup it even need to connect the OS environment but on my method i dont use the google auth
but directly implement the credentials.
    // Fetch data from BigQuery
    const bigquery = new BigQuery({
      projectId: "annular-moon-361814",
      credentials: {
        private_key: process.env.GBQ_PRIVATE_KEY,
        client_email: process.env.GBQ_EMAIL_CLIENT,
      },
    });
ic. so basically avoid using crash or corrupt, make it precise. returning 500 means the Node.js server is still alive not crash not corupt, just your codes or libraries failed.
double check libraries versions, especially google-auth-library, google for exceptions you got.
i have experience with GCP lib version glitch before.
@tafutada777 ic. so basically avoid using crash or corrupt, make it precise. returning 500 means the Node.js server is still alive not crash not corupt, just your codes or libraries failed. double check libraries versions, especially google-auth-library, google for exceptions you got.
Giant wood waspOP
i dont use google auth, i only @google-cloud/bigquery
it works on localhost.

and SOMETIMES on production it is working, but most of the time when i push new feature. it encounter that issue.

oh ic, i should just return status(400)
when should i return status 500?
i saw the said lib in the exception stack trace.
Vercel loads libraries in package.json, so check the versions of libs right.
400 are authentication/authorizatin error, 500 are app error returned from ur code, or gateway/timeout error to Redis/BigQuery returned by vercel runtime.
did you store GCP service account in Vercel env?
@tafutada777 did you store GCP service account in Vercel env?
Giant wood waspOP
yeah a bit similar issue,
but i dot use full service account or google-auth.
only use credentials private_key and client_email

it mentioned the culprit is bad privatekey, it might be but what's weird, the error isn't consistent.
at somepoint the next/api is working.

for now 2 new same query in different api route, 1 of them has failed.
both same query, same setup, same pvt-key
only route name differences, and only on production i encountered this.
all clue we have is the stack trace, which i googled says malformed, wrong format, encompassed with double quotes(") or something...
@tafutada777 all clue we have is the stack trace, which i googled says malformed, wrong format, encompassed with double quotes(") or something...
Giant wood waspOP
i did return 400 api and it still app error ?

Application error: a client-side exception has occurred (see the browser console for more information).


how do i prevent this? i meant it is just a failure of next/api but why my entire app isnt working?
usually if failed api, at least the data is undefined and my shimmer/loader will show up but idk with this bigquery next/api crash my whole app on production
so what do you mean by crash? show me the output of curl?