fix(chat): handle inactive botid gracefully (#1437)

This commit is contained in:
dancer 2026-03-02 15:06:22 +00:00 committed by GitHub
parent ad47aa0ee0
commit 314f8ced57
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 30 additions and 9 deletions

View file

@ -1,6 +1,7 @@
import type { NextAuthConfig } from "next-auth";
export const authConfig = {
basePath: "/api/auth",
pages: {
signIn: "/login",
newUser: "/",

View file

@ -1,4 +1,3 @@
import { checkBotId } from "botid/server";
import { geolocation, ipAddress } from "@vercel/functions";
import {
convertToModelMessages,
@ -8,6 +7,7 @@ import {
stepCountIs,
streamText,
} from "ai";
import { checkBotId } from "botid/server";
import { after } from "next/server";
import { createResumableStreamContext } from "resumable-stream";
import { auth, type UserType } from "@/app/(auth)/auth";
@ -64,9 +64,12 @@ export async function POST(request: Request) {
const { id, message, messages, selectedChatModel, selectedVisibilityType } =
requestBody;
const [botResult, session] = await Promise.all([checkBotId(), auth()]);
const [botResult, session] = await Promise.all([
checkBotId().catch(() => null),
auth(),
]);
if (botResult.isBot) {
if (botResult?.isBot) {
return new ChatbotError("unauthorized:chat").toResponse();
}

View file

@ -3,7 +3,7 @@ import { initBotId } from "botid/client/core";
initBotId({
protect: [
{
path: "/api/chat",
path: `${process.env.NEXT_PUBLIC_BASE_PATH ?? ""}/api/chat`,
method: "POST",
},
],

View file

@ -11,7 +11,7 @@ let client: ReturnType<typeof createClient> | null = null;
function getClient() {
if (!client && process.env.REDIS_URL) {
client = createClient({ url: process.env.REDIS_URL });
client.on("error", () => {});
client.on("error", () => undefined);
client.connect().catch(() => {
client = null;
});
@ -20,10 +20,14 @@ function getClient() {
}
export async function checkIpRateLimit(ip: string | undefined) {
if (!isProductionEnvironment || !ip) return;
if (!isProductionEnvironment || !ip) {
return;
}
const redis = getClient();
if (!redis?.isReady) return;
if (!redis?.isReady) {
return;
}
try {
const key = `ip-rate-limit:${ip}`;
@ -37,6 +41,8 @@ export async function checkIpRateLimit(ip: string | undefined) {
throw new ChatbotError("rate_limit:chat");
}
} catch (error) {
if (error instanceof ChatbotError) throw error;
if (error instanceof ChatbotError) {
throw error;
}
}
}

View file

@ -1,5 +1,5 @@
import type { NextConfig } from "next";
import { withBotId } from "botid/next/config";
import type { NextConfig } from "next";
const basePath = "/demo";
@ -8,6 +8,7 @@ const nextConfig: NextConfig = {
assetPrefix: "/demo-assets",
env: {
NEXT_PUBLIC_BASE_PATH: basePath,
NEXTAUTH_URL: `http://localhost${basePath}/api/auth`,
},
cacheComponents: true,
images: {

View file

@ -1,5 +1,15 @@
{
"framework": "nextjs",
"rewrites": [
{
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/a-4-a/c.js",
"destination": "https://api.vercel.com/bot-protection/v1/challenge"
},
{
"source": "/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/:path*",
"destination": "https://api.vercel.com/bot-protection/v1/proxy/:path*"
}
],
"redirects": [
{
"source": "/",