mirror of
https://github.com/jakejarvis/jarv.is.git
synced 2025-07-21 19:01:17 -04:00
retry on Fauna "contended transaction" error, see https://sentry.io/share/issue/9c60a58211954ed7a8dfbe289bd107b5/
This commit is contained in:
@@ -2,18 +2,18 @@ import * as Sentry from "@sentry/node";
|
||||
import fetch from "node-fetch";
|
||||
import queryString from "query-string";
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN || "",
|
||||
environment: process.env.NODE_ENV || process.env.VERCEL_ENV || "",
|
||||
});
|
||||
|
||||
// fallback to dummy secret for testing: https://docs.hcaptcha.com/#integration-testing-test-keys
|
||||
const HCAPTCHA_SITE_KEY = process.env.HCAPTCHA_SITE_KEY || "10000000-ffff-ffff-ffff-000000000001";
|
||||
const HCAPTCHA_SECRET_KEY = process.env.HCAPTCHA_SECRET_KEY || "0x0000000000000000000000000000000000000000";
|
||||
const HCAPTCHA_API_ENDPOINT = "https://hcaptcha.com/siteverify";
|
||||
|
||||
const { AIRTABLE_API_KEY, AIRTABLE_BASE } = process.env;
|
||||
const AIRTABLE_API_ENDPOINT = `https://api.airtable.com/v0/`;
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN || "",
|
||||
environment: process.env.NODE_ENV || process.env.VERCEL_ENV || "",
|
||||
});
|
||||
const AIRTABLE_API_ENDPOINT = "https://api.airtable.com/v0/";
|
||||
|
||||
export default async (req, res) => {
|
||||
// disable caching on both ends
|
||||
@@ -38,7 +38,7 @@ export default async (req, res) => {
|
||||
|
||||
// these are both backups to client-side validations just in case someone squeezes through without them. the codes
|
||||
// are identical so they're caught in the same fashion.
|
||||
if (!body.name || !body.email || !body.message) {
|
||||
if (!body || !body.name || !body.email || !body.message) {
|
||||
// all fields are required
|
||||
throw new Error("USER_MISSING_DATA");
|
||||
}
|
||||
|
21
api/hits.js
21
api/hits.js
@@ -2,25 +2,26 @@ import * as Sentry from "@sentry/node";
|
||||
import fetch from "node-fetch";
|
||||
import parser from "fast-xml-parser";
|
||||
import { decode } from "html-entities";
|
||||
import pRetry from "p-retry";
|
||||
import faunadb from "faunadb";
|
||||
const q = faunadb.query;
|
||||
|
||||
const BASE_URL = "https://jarv.is/";
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN || "",
|
||||
environment: process.env.NODE_ENV || process.env.VERCEL_ENV || "",
|
||||
});
|
||||
|
||||
const BASE_URL = "https://jarv.is/";
|
||||
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
// some rudimentary error handling
|
||||
if (!process.env.FAUNADB_SERVER_SECRET) {
|
||||
throw new Error("Database credentials aren't set.");
|
||||
}
|
||||
if (req.method !== "GET") {
|
||||
throw new Error(`Method ${req.method} not allowed.`);
|
||||
}
|
||||
if (!process.env.FAUNADB_SERVER_SECRET) {
|
||||
throw new Error("Database credentials aren't set.");
|
||||
}
|
||||
|
||||
const client = new faunadb.Client({
|
||||
secret: process.env.FAUNADB_SERVER_SECRET,
|
||||
@@ -36,8 +37,14 @@ export default async (req, res) => {
|
||||
// let Vercel edge and browser cache results for 15 mins
|
||||
res.setHeader("Cache-Control", "public, max-age=900, s-maxage=900, stale-while-revalidate");
|
||||
} else {
|
||||
// increment this page's hits
|
||||
result = await incrementPageHits(slug, client);
|
||||
// increment this page's hits. retry 3 times in case of Fauna "contended transaction" error:
|
||||
// https://sentry.io/share/issue/9c60a58211954ed7a8dfbe289bd107b5/
|
||||
result = await pRetry(() => incrementPageHits(slug, client), {
|
||||
onFailedAttempt: (error) => {
|
||||
console.warn(`Attempt ${error.attemptNumber} failed, trying again...`);
|
||||
},
|
||||
retries: 3,
|
||||
});
|
||||
|
||||
// disable caching on both ends
|
||||
res.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate");
|
||||
|
@@ -5,21 +5,21 @@ import * as Sentry from "@sentry/node";
|
||||
import fetch from "node-fetch";
|
||||
import queryString from "query-string";
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN || "",
|
||||
environment: process.env.NODE_ENV || process.env.VERCEL_ENV || "",
|
||||
});
|
||||
|
||||
const { SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, SPOTIFY_REFRESH_TOKEN } = process.env;
|
||||
|
||||
const basic = Buffer.from(`${SPOTIFY_CLIENT_ID}:${SPOTIFY_CLIENT_SECRET}`).toString("base64");
|
||||
|
||||
// https://developer.spotify.com/documentation/general/guides/authorization-guide/#authorization-code-flow
|
||||
const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`;
|
||||
const TOKEN_ENDPOINT = "https://accounts.spotify.com/api/token";
|
||||
// https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-the-users-currently-playing-track
|
||||
const NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`;
|
||||
const NOW_PLAYING_ENDPOINT = "https://api.spotify.com/v1/me/player/currently-playing";
|
||||
// https://developer.spotify.com/documentation/web-api/reference/#endpoint-get-users-top-artists-and-tracks
|
||||
const TOP_TRACKS_ENDPOINT = `https://api.spotify.com/v1/me/top/tracks?time_range=long_term&limit=10`;
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.SENTRY_DSN || "",
|
||||
environment: process.env.NODE_ENV || process.env.VERCEL_ENV || "",
|
||||
});
|
||||
const TOP_TRACKS_ENDPOINT = "https://api.spotify.com/v1/me/top/tracks?time_range=long_term&limit=10";
|
||||
|
||||
export default async (req, res) => {
|
||||
try {
|
||||
|
Reference in New Issue
Block a user