mirror of
https://github.com/trafficlunar/tomodachi-share.git
synced 2026-05-13 13:17:45 +00:00
Compare commits
2 commits
3a5243fa3e
...
e500cefcc2
| Author | SHA1 | Date | |
|---|---|---|---|
| e500cefcc2 | |||
| 144240e278 |
20 changed files with 5 additions and 2010 deletions
|
|
@ -9,10 +9,6 @@ NEXT_PUBLIC_BASE_URL=http://localhost:3000
|
|||
CLOUDFLARE_ZONE_ID=XXXXXXXXXXXXXXXX
|
||||
CLOUDFLARE_API_TOKEN=XXXXXXXXXXXXXXXX
|
||||
|
||||
# Used for error tracking
|
||||
NEXT_PUBLIC_SENTRY_DSN=""
|
||||
SENTRY_URL=""
|
||||
|
||||
# Check Auth.js docs for information
|
||||
AUTH_URL=http://localhost:3000 # This should be the same as NEXT_PUBLIC_BASE_URL
|
||||
AUTH_TRUST_HOST=true
|
||||
|
|
|
|||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -44,5 +44,3 @@ next-env.d.ts
|
|||
|
||||
# tomodachi-share
|
||||
uploads/
|
||||
# Sentry Config File
|
||||
.env.sentry-build-plugin
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import { withSentryConfig } from "@sentry/nextjs";
|
||||
import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
|
|
@ -8,41 +7,4 @@ const nextConfig: NextConfig = {
|
|||
},
|
||||
};
|
||||
|
||||
export default withSentryConfig(nextConfig, {
|
||||
// For all available options, see:
|
||||
// https://www.npmjs.com/package/@sentry/webpack-plugin#options
|
||||
|
||||
org: "trafficlunar",
|
||||
|
||||
project: "tomodachishare",
|
||||
sentryUrl: process.env.SENTRY_URL,
|
||||
|
||||
// Only print logs for uploading source maps in CI
|
||||
silent: !process.env.CI,
|
||||
|
||||
// For all available options, see:
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
|
||||
|
||||
// Upload a larger set of source maps for prettier stack traces (increases build time)
|
||||
widenClientFileUpload: true,
|
||||
|
||||
// Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
|
||||
// This can increase your server load as well as your hosting bill.
|
||||
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
|
||||
// side errors will fail.
|
||||
// tunnelRoute: "/monitoring",
|
||||
|
||||
webpack: {
|
||||
// Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
|
||||
// See the following for more information:
|
||||
// https://docs.sentry.io/product/crons/
|
||||
// https://vercel.com/docs/cron-jobs
|
||||
automaticVercelMonitors: false,
|
||||
|
||||
// Tree-shaking options for reducing bundle size
|
||||
treeshake: {
|
||||
// Automatically tree-shake Sentry logger statements to reduce bundle size
|
||||
removeDebugLogging: true,
|
||||
},
|
||||
},
|
||||
});
|
||||
export default nextConfig;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
"@bprogress/next": "^3.2.12",
|
||||
"@hello-pangea/dnd": "^18.0.1",
|
||||
"@prisma/client": "^6.19.2",
|
||||
"@sentry/nextjs": "^10.48.0",
|
||||
"bit-buffer": "^0.3.0",
|
||||
"canvas-confetti": "^1.9.4",
|
||||
"dayjs": "^1.11.20",
|
||||
|
|
|
|||
1830
pnpm-lock.yaml
1830
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +0,0 @@
|
|||
// This file configures the initialization of Sentry on the server.
|
||||
// The config you add here will be used whenever the server handles a request.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
|
||||
tracesSampleRate: 0.1,
|
||||
// Enable logs to be sent to Sentry
|
||||
enableLogs: true,
|
||||
// Enable sending user PII (Personally Identifiable Information)
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii
|
||||
sendDefaultPii: false,
|
||||
});
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { profanity } from "@2toad/profanity";
|
||||
import z from "zod";
|
||||
|
||||
|
|
@ -10,7 +9,6 @@ import { RateLimit } from "@/lib/rate-limit";
|
|||
export async function PATCH(request: NextRequest) {
|
||||
const session = await auth();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user?.id, name: session.user?.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 3);
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -29,7 +27,6 @@ export async function PATCH(request: NextRequest) {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update description:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "update-about-me" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to update description" }, 500);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
import { auth } from "@/lib/auth";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
|
@ -8,7 +7,6 @@ import { RateLimit } from "@/lib/rate-limit";
|
|||
export async function DELETE(request: NextRequest) {
|
||||
const session = await auth();
|
||||
if (!session || !session.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user.id, name: session.user.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 1);
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -20,7 +18,6 @@ export async function DELETE(request: NextRequest) {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to delete user:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "delete-account" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to delete account" }, 500);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { profanity } from "@2toad/profanity";
|
||||
|
||||
import { auth } from "@/lib/auth";
|
||||
|
|
@ -10,7 +9,6 @@ import { RateLimit } from "@/lib/rate-limit";
|
|||
export async function PATCH(request: NextRequest) {
|
||||
const session = await auth();
|
||||
if (!session || !session.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user.id, name: session.user.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 3);
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -32,7 +30,6 @@ export async function PATCH(request: NextRequest) {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update name:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "update-name" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to update name" }, 500);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import dayjs from "dayjs";
|
||||
import { z } from "zod";
|
||||
|
||||
|
|
@ -21,7 +20,6 @@ const formDataSchema = z.object({
|
|||
export async function PATCH(request: NextRequest) {
|
||||
const session = await auth();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user?.id, name: session.user?.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 3);
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -70,7 +68,6 @@ export async function PATCH(request: NextRequest) {
|
|||
await fs.writeFile(fileLocation, pngBuffer);
|
||||
} catch (error) {
|
||||
console.error("Error uploading profile picture:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "upload-profile-picture" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to store profile picture" }, 500);
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +78,6 @@ export async function PATCH(request: NextRequest) {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to update profile picture:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "update-profile-picture" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to update profile picture" }, 500);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
|
|
@ -14,7 +13,6 @@ const uploadsDirectory = path.join(process.cwd(), "uploads", "mii");
|
|||
export async function DELETE(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||
const session = await auth();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user?.id, name: session.user?.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 30, "/api/mii/delete");
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -44,7 +42,6 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to delete Mii from database:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "delete-mii" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to delete Mii" }, 500);
|
||||
}
|
||||
|
||||
|
|
@ -52,7 +49,6 @@ export async function DELETE(request: NextRequest, { params }: { params: Promise
|
|||
await fs.rm(miiUploadsDirectory, { recursive: true, force: true });
|
||||
} catch (error) {
|
||||
console.warn("Failed to delete Mii image files:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "delete-mii-images" } });
|
||||
}
|
||||
|
||||
return rateLimit.sendResponse({ success: true });
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { z } from "zod";
|
||||
import { Mii, MiiGender, MiiMakeup, Prisma } from "@prisma/client";
|
||||
import { MiiGender, MiiMakeup, Prisma } from "@prisma/client";
|
||||
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
|
|
@ -46,7 +45,6 @@ const editSchema = z.object({
|
|||
export async function PATCH(request: NextRequest, { params }: { params: Promise<{ id: string }> }) {
|
||||
const session = await auth();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user?.id, name: session.user?.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 6); // no grouped pathname; edit each mii 2 times a minute
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -192,7 +190,6 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
|||
);
|
||||
} catch (error) {
|
||||
console.error("Error uploading user images:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "edit-custom-images" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to store user images" }, 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -232,7 +229,6 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
|||
);
|
||||
} catch (error) {
|
||||
console.error("Error uploading portrait/features images:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "edit-portrait-features" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to store portrait/features images" }, 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -257,7 +253,6 @@ export async function PATCH(request: NextRequest, { params }: { params: Promise<
|
|||
}),
|
||||
}).catch((err) => {
|
||||
console.error("Cloudflare cache purge failed:", err);
|
||||
Sentry.captureException(err, { extra: { stage: "cloudflare-purge", miiId } });
|
||||
});
|
||||
|
||||
return rateLimit.sendResponse({ success: true });
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { z } from "zod";
|
||||
import { Prisma, ReportReason, ReportType } from "@prisma/client";
|
||||
|
||||
|
|
@ -19,7 +18,6 @@ const reportSchema = z.object({
|
|||
export async function POST(request: NextRequest) {
|
||||
const session = await auth();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user?.id, name: session.user?.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 2);
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -85,7 +83,6 @@ export async function POST(request: NextRequest) {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Report creation failed", error);
|
||||
Sentry.captureException(error, { extra: { stage: "create-report" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to create report" }, 500);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { z } from "zod";
|
||||
|
||||
import fs from "fs/promises";
|
||||
|
|
@ -76,7 +75,6 @@ const submitSchema = z
|
|||
export async function POST(request: NextRequest) {
|
||||
const session = await auth();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
Sentry.setUser({ id: session.user?.id, name: session.user?.name });
|
||||
|
||||
const rateLimit = new RateLimit(request, 3);
|
||||
const check = await rateLimit.handle();
|
||||
|
|
@ -92,9 +90,6 @@ export async function POST(request: NextRequest) {
|
|||
rawTags = JSON.parse(formData.get("tags") as string);
|
||||
rawQrBytesRaw = JSON.parse(formData.get("qrBytesRaw") as string);
|
||||
} catch (error) {
|
||||
Sentry.captureException(error, {
|
||||
extra: { stage: "submit-json-parse" },
|
||||
});
|
||||
return rateLimit.sendResponse({ error: "Invalid JSON in tags or QR code data" }, 400);
|
||||
}
|
||||
|
||||
|
|
@ -128,15 +123,6 @@ export async function POST(request: NextRequest) {
|
|||
const firstIssue = parsed.error.issues[0];
|
||||
const path = firstIssue.path.length ? firstIssue.path.join(".") : "root";
|
||||
const error = `${path}: ${firstIssue.message}`;
|
||||
const issues = parsed.error.issues;
|
||||
const hasInstructionsErrors = issues.some((issue) => issue.path[0] === "instructions");
|
||||
|
||||
if (hasInstructionsErrors) {
|
||||
Sentry.captureException(error, {
|
||||
extra: { issues, rawInstructions: formData.get("instructions"), stage: "submit-instructions" },
|
||||
});
|
||||
}
|
||||
|
||||
return rateLimit.sendResponse({ error }, 400);
|
||||
}
|
||||
const {
|
||||
|
|
@ -192,7 +178,6 @@ export async function POST(request: NextRequest) {
|
|||
try {
|
||||
conversion = convertQrCode(qrBytes);
|
||||
} catch (error) {
|
||||
Sentry.captureException(error, { extra: { stage: "qr-conversion" } });
|
||||
return rateLimit.sendResponse({ error: error instanceof Error ? error.message : String(error) }, 400);
|
||||
}
|
||||
}
|
||||
|
|
@ -277,7 +262,6 @@ export async function POST(request: NextRequest) {
|
|||
await prisma.mii.delete({ where: { id: miiRecord.id } });
|
||||
|
||||
console.error("Failed to download/store Mii portrait/features:", error);
|
||||
Sentry.captureException(error, { extra: { miiId: miiRecord.id, stage: "studio-image-download" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to download/store Mii portrait/features" }, 500);
|
||||
}
|
||||
|
||||
|
|
@ -285,7 +269,6 @@ export async function POST(request: NextRequest) {
|
|||
await generateMetadataImage(miiRecord, session.user?.name!);
|
||||
} catch (error) {
|
||||
console.error("Failed to generate metadata image:", error);
|
||||
Sentry.captureException(error, { extra: { miiId: miiRecord.id, stage: "metadata-image-generation" } });
|
||||
}
|
||||
|
||||
if (platform === "THREE_DS") {
|
||||
|
|
@ -311,7 +294,6 @@ export async function POST(request: NextRequest) {
|
|||
await prisma.mii.delete({ where: { id: miiRecord.id } });
|
||||
|
||||
console.error("Error processing Mii files:", error);
|
||||
Sentry.captureException(error, { extra: { miiId: miiRecord.id, stage: "file-processing" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to process and store Mii files" }, 500);
|
||||
}
|
||||
}
|
||||
|
|
@ -339,8 +321,6 @@ export async function POST(request: NextRequest) {
|
|||
});
|
||||
} catch (error) {
|
||||
console.error("Error storing user images:", error);
|
||||
|
||||
Sentry.captureException(error, { extra: { miiId: miiRecord.id, stage: "user-image-storage" } });
|
||||
return rateLimit.sendResponse({ error: "Failed to store user images" }, 500);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
"use client";
|
||||
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import NextError from "next/error";
|
||||
import { useEffect } from "react";
|
||||
|
||||
export default function GlobalError({ error }: { error: Error & { digest?: string } }) {
|
||||
useEffect(() => {
|
||||
Sentry.captureException(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<html lang="en">
|
||||
<body>
|
||||
{/* `NextError` is the default Next.js error page component. Its type
|
||||
definition requires a `statusCode` prop. However, since the App Router
|
||||
does not expose status codes for errors, we simply pass 0 to render a
|
||||
generic error message. */}
|
||||
<NextError statusCode={0} />
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ export default function PrivacyPage() {
|
|||
<div className="bg-amber-50 border-2 border-amber-500 rounded-2xl p-6">
|
||||
<h1 className="text-2xl font-bold">Privacy Policy</h1>
|
||||
<h2 className="font-light">
|
||||
<strong className="font-medium">Effective Date:</strong> 21 February 2026
|
||||
<strong className="font-medium">Effective Date:</strong> 13 April 2026
|
||||
</h2>
|
||||
|
||||
<hr className="border-black/20 mt-1 mb-4" />
|
||||
|
|
@ -65,23 +65,6 @@ export default function PrivacyPage() {
|
|||
</p>
|
||||
</section>
|
||||
</li>
|
||||
<li>
|
||||
<h3 className="text-xl font-semibold mt-6 mb-2">Error Reporting</h3>
|
||||
<section>
|
||||
<p className="mb-2">
|
||||
This website uses{" "}
|
||||
<a href="https://glitchtip.com/" className="text-blue-700">
|
||||
GlitchTip
|
||||
</a>{" "}
|
||||
(a self-hosted Sentry-like instance) to monitor errors and site performance. To protect your privacy:
|
||||
</p>
|
||||
<ul className="list-disc list-inside ml-4">
|
||||
<li>Errors and performance data is collected.</li>
|
||||
<li>Only your user ID and name are sent, no other personally identifiable information is collected.</li>
|
||||
<li>You can use ad blockers or browser privacy features to opt out.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</li>
|
||||
<li>
|
||||
<h3 className="text-xl font-semibold mt-6 mb-2">Data Sharing</h3>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
// This file configures the initialization of Sentry on the client.
|
||||
// The added config here will be used whenever a users loads a page in their browser.
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
|
||||
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
Sentry.init({
|
||||
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
|
||||
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
|
||||
tracesSampleRate: 0.1,
|
||||
// Enable logs to be sent to Sentry
|
||||
enableLogs: true,
|
||||
// Enable sending user PII (Personally Identifiable Information)
|
||||
// https://docs.sentry.io/platforms/javascript/guides/nextjs/configuration/options/#sendDefaultPii
|
||||
sendDefaultPii: false,
|
||||
});
|
||||
|
||||
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
export async function register() {
|
||||
if (process.env.NEXT_RUNTIME === "nodejs") {
|
||||
await import("../sentry.server.config");
|
||||
}
|
||||
}
|
||||
|
||||
export const onRequestError = Sentry.captureRequestError;
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
/* eslint-disable @next/next/no-img-element */
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
|
|
@ -55,7 +54,6 @@ export async function validateImage(file: File): Promise<{ valid: boolean; error
|
|||
return { valid: true };
|
||||
} catch (error) {
|
||||
console.error("Error validating image:", error);
|
||||
Sentry.captureException(error, { extra: { stage: "image-validation" } });
|
||||
return { valid: false, error: "Failed to process image file", status: 500 };
|
||||
}
|
||||
}
|
||||
|
|
@ -217,7 +215,6 @@ export async function generateMetadataImage(mii: Mii, author: string): Promise<{
|
|||
await fs.writeFile(fileLocation, buffer);
|
||||
} catch (error) {
|
||||
console.error("Error storing 'metadata' image type", error);
|
||||
Sentry.captureException(error, { extra: { stage: "metadata-image-storage", miiId: mii.id } });
|
||||
return { error: `Failed to store metadata image for ${mii.id}`, status: 500 };
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { createClient, RedisClientType } from "redis";
|
||||
import * as Sentry from "@sentry/nextjs";
|
||||
import { auth } from "./auth";
|
||||
|
||||
const WINDOW_SIZE = 60;
|
||||
|
|
@ -20,7 +19,6 @@ async function getRedisClient() {
|
|||
});
|
||||
client.on("error", (error) => {
|
||||
console.error("Redis client error", error);
|
||||
Sentry.captureException(error, { tags: { source: "redis-client" } });
|
||||
});
|
||||
await client.connect();
|
||||
}
|
||||
|
|
@ -71,7 +69,6 @@ export class RateLimit {
|
|||
return { success, limit: this.maxRequests, remaining, expires: expireAt };
|
||||
} catch (error) {
|
||||
console.error("Rate limit check failed", error);
|
||||
Sentry.captureException(error, { tags: { source: "rate-limit-check" } });
|
||||
return {
|
||||
success: false,
|
||||
limit: this.maxRequests,
|
||||
|
|
|
|||
Loading…
Reference in a new issue