fix: linting and document limit

This commit is contained in:
DESKTOP-RTLN3BA\$punk 2025-09-18 17:46:51 -07:00
parent 0474a114d9
commit c2897d7fbe
5 changed files with 193 additions and 194 deletions

View file

@ -157,7 +157,7 @@ async def create_documents_file_upload(
@router.get("/documents/", response_model=list[DocumentRead]) @router.get("/documents/", response_model=list[DocumentRead])
async def read_documents( async def read_documents(
skip: int = 0, skip: int = 0,
limit: int = 3000, limit: int = 300,
search_space_id: int | None = None, search_space_id: int | None = None,
session: AsyncSession = Depends(get_async_session), session: AsyncSession = Depends(get_async_session),
user: User = Depends(current_active_user), user: User = Depends(current_active_user),

View file

@ -1,10 +1,10 @@
"use client"; "use client";
import { AnimatePresence, motion } from "framer-motion";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { toast } from "sonner"; import { toast } from "sonner";
import { getAuthErrorDetails, shouldRetry, isNetworkError } from "@/lib/auth-errors"; import { getAuthErrorDetails, isNetworkError, shouldRetry } from "@/lib/auth-errors";
export function LocalLoginForm() { export function LocalLoginForm() {
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
@ -64,31 +64,30 @@ export function LocalLoginForm() {
setTimeout(() => { setTimeout(() => {
router.push(`/auth/callback?token=${data.access_token}`); router.push(`/auth/callback?token=${data.access_token}`);
}, 500); }, 500);
} catch (err) { } catch (err) {
// Use auth-errors utility to get proper error details // Use auth-errors utility to get proper error details
let errorCode = "UNKNOWN_ERROR"; let errorCode = "UNKNOWN_ERROR";
if (err instanceof Error) { if (err instanceof Error) {
errorCode = err.message; errorCode = err.message;
} else if (isNetworkError(err)) { } else if (isNetworkError(err)) {
errorCode = "NETWORK_ERROR"; errorCode = "NETWORK_ERROR";
} }
// Get detailed error information from auth-errors utility // Get detailed error information from auth-errors utility
const errorDetails = getAuthErrorDetails(errorCode); const errorDetails = getAuthErrorDetails(errorCode);
// Set persistent error display // Set persistent error display
setErrorTitle(errorDetails.title); setErrorTitle(errorDetails.title);
setError(errorDetails.description); setError(errorDetails.description);
// Show error toast with conditional retry action // Show error toast with conditional retry action
const toastOptions: any = { const toastOptions: any = {
id: loadingToast, id: loadingToast,
description: errorDetails.description, description: errorDetails.description,
duration: 6000, duration: 6000,
}; };
// Add retry action if the error is retryable // Add retry action if the error is retryable
if (shouldRetry(errorCode)) { if (shouldRetry(errorCode)) {
toastOptions.action = { toastOptions.action = {
@ -96,7 +95,7 @@ export function LocalLoginForm() {
onClick: () => handleSubmit(e), onClick: () => handleSubmit(e),
}; };
} }
toast.error(errorDetails.title, toastOptions); toast.error(errorDetails.title, toastOptions);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
@ -136,9 +135,7 @@ export function LocalLoginForm() {
</svg> </svg>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<p className="text-sm font-semibold mb-1">{errorTitle}</p> <p className="text-sm font-semibold mb-1">{errorTitle}</p>
<p className="text-sm text-red-700 dark:text-red-300"> <p className="text-sm text-red-700 dark:text-red-300">{error}</p>
{error}
</p>
</div> </div>
<button <button
onClick={() => { onClick={() => {

View file

@ -1,12 +1,12 @@
"use client"; "use client";
import { AnimatePresence, motion } from "framer-motion";
import { Loader2 } from "lucide-react"; import { Loader2 } from "lucide-react";
import { useSearchParams } from "next/navigation"; import { useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react"; import { Suspense, useEffect, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { toast } from "sonner"; import { toast } from "sonner";
import { getAuthErrorDetails, shouldRetry } from "@/lib/auth-errors";
import { Logo } from "@/components/Logo"; import { Logo } from "@/components/Logo";
import { getAuthErrorDetails, shouldRetry } from "@/lib/auth-errors";
import { AmbientBackground } from "./AmbientBackground"; import { AmbientBackground } from "./AmbientBackground";
import { GoogleLoginButton } from "./GoogleLoginButton"; import { GoogleLoginButton } from "./GoogleLoginButton";
import { LocalLoginForm } from "./LocalLoginForm"; import { LocalLoginForm } from "./LocalLoginForm";
@ -44,14 +44,14 @@ function LoginContent() {
if (error) { if (error) {
// Use the auth-errors utility to get proper error details // Use the auth-errors utility to get proper error details
const errorDetails = getAuthErrorDetails(error); const errorDetails = getAuthErrorDetails(error);
// If we have a custom message from URL params, use it as description // If we have a custom message from URL params, use it as description
const errorDescription = message ? decodeURIComponent(message) : errorDetails.description; const errorDescription = message ? decodeURIComponent(message) : errorDetails.description;
// Set persistent error display // Set persistent error display
setUrlError({ setUrlError({
title: errorDetails.title, title: errorDetails.title,
message: errorDescription message: errorDescription,
}); });
// Show toast with conditional retry action // Show toast with conditional retry action
@ -59,7 +59,7 @@ function LoginContent() {
description: errorDescription, description: errorDescription,
duration: 6000, duration: 6000,
}; };
// Add retry action if the error is retryable // Add retry action if the error is retryable
if (shouldRetry(error)) { if (shouldRetry(error)) {
toastOptions.action = { toastOptions.action = {
@ -67,7 +67,7 @@ function LoginContent() {
onClick: () => window.location.reload(), onClick: () => window.location.reload(),
}; };
} }
toast.error(errorDetails.title, toastOptions); toast.error(errorDetails.title, toastOptions);
} }
@ -143,9 +143,7 @@ function LoginContent() {
</svg> </svg>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<p className="text-sm font-semibold mb-1">{urlError.title}</p> <p className="text-sm font-semibold mb-1">{urlError.title}</p>
<p className="text-sm text-red-700 dark:text-red-300"> <p className="text-sm text-red-700 dark:text-red-300">{urlError.message}</p>
{urlError.message}
</p>
</div> </div>
<button <button
onClick={() => setUrlError(null)} onClick={() => setUrlError(null)}

View file

@ -1,12 +1,12 @@
"use client"; "use client";
import { AnimatePresence, motion } from "framer-motion";
import Link from "next/link"; import Link from "next/link";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { motion, AnimatePresence } from "framer-motion";
import { toast } from "sonner"; import { toast } from "sonner";
import { getAuthErrorDetails, shouldRetry, isNetworkError } from "@/lib/auth-errors";
import { Logo } from "@/components/Logo"; import { Logo } from "@/components/Logo";
import { getAuthErrorDetails, isNetworkError, shouldRetry } from "@/lib/auth-errors";
import { AmbientBackground } from "../login/AmbientBackground"; import { AmbientBackground } from "../login/AmbientBackground";
export default function RegisterPage() { export default function RegisterPage() {
@ -79,31 +79,30 @@ export default function RegisterPage() {
setTimeout(() => { setTimeout(() => {
router.push("/login?registered=true"); router.push("/login?registered=true");
}, 500); }, 500);
} catch (err) { } catch (err) {
// Use auth-errors utility to get proper error details // Use auth-errors utility to get proper error details
let errorCode = "UNKNOWN_ERROR"; let errorCode = "UNKNOWN_ERROR";
if (err instanceof Error) { if (err instanceof Error) {
errorCode = err.message; errorCode = err.message;
} else if (isNetworkError(err)) { } else if (isNetworkError(err)) {
errorCode = "NETWORK_ERROR"; errorCode = "NETWORK_ERROR";
} }
// Get detailed error information from auth-errors utility // Get detailed error information from auth-errors utility
const errorDetails = getAuthErrorDetails(errorCode); const errorDetails = getAuthErrorDetails(errorCode);
// Set persistent error display // Set persistent error display
setErrorTitle(errorDetails.title); setErrorTitle(errorDetails.title);
setError(errorDetails.description); setError(errorDetails.description);
// Show error toast with conditional retry action // Show error toast with conditional retry action
const toastOptions: any = { const toastOptions: any = {
id: loadingToast, id: loadingToast,
description: errorDetails.description, description: errorDetails.description,
duration: 6000, duration: 6000,
}; };
// Add retry action if the error is retryable // Add retry action if the error is retryable
if (shouldRetry(errorCode)) { if (shouldRetry(errorCode)) {
toastOptions.action = { toastOptions.action = {
@ -111,7 +110,7 @@ export default function RegisterPage() {
onClick: () => handleSubmit(e), onClick: () => handleSubmit(e),
}; };
} }
toast.error(errorDetails.title, toastOptions); toast.error(errorDetails.title, toastOptions);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
@ -159,9 +158,7 @@ export default function RegisterPage() {
</svg> </svg>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<p className="text-sm font-semibold mb-1">{errorTitle}</p> <p className="text-sm font-semibold mb-1">{errorTitle}</p>
<p className="text-sm text-red-700 dark:text-red-300"> <p className="text-sm text-red-700 dark:text-red-300">{error}</p>
{error}
</p>
</div> </div>
<button <button
onClick={() => { onClick={() => {

View file

@ -3,110 +3,110 @@
*/ */
interface AuthErrorMapping { interface AuthErrorMapping {
[key: string]: { [key: string]: {
title: string; title: string;
description?: string; description?: string;
}; };
} }
const AUTH_ERROR_MESSAGES: AuthErrorMapping = { const AUTH_ERROR_MESSAGES: AuthErrorMapping = {
// Common HTTP errors // Common HTTP errors
"401": { "401": {
title: "Invalid credentials", title: "Invalid credentials",
description: "Please check your email and password" description: "Please check your email and password",
}, },
"403": { "403": {
title: "Access denied", title: "Access denied",
description: "Your account may be suspended or restricted" description: "Your account may be suspended or restricted",
}, },
"404": { "404": {
title: "Account not found", title: "Account not found",
description: "No account exists with this email address" description: "No account exists with this email address",
}, },
"409": { "409": {
title: "Account conflict", title: "Account conflict",
description: "An account with this email already exists" description: "An account with this email already exists",
}, },
"429": { "429": {
title: "Too many attempts", title: "Too many attempts",
description: "Please wait before trying again" description: "Please wait before trying again",
}, },
"500": { "500": {
title: "Server error", title: "Server error",
description: "Something went wrong on our end. Please try again" description: "Something went wrong on our end. Please try again",
}, },
"503": { "503": {
title: "Service unavailable", title: "Service unavailable",
description: "Login service is temporarily down" description: "Login service is temporarily down",
}, },
// FastAPI specific errors // FastAPI specific errors
"LOGIN_BAD_CREDENTIALS": { LOGIN_BAD_CREDENTIALS: {
title: "Invalid credentials", title: "Invalid credentials",
description: "The email or password you entered is incorrect" description: "The email or password you entered is incorrect",
}, },
"LOGIN_USER_NOT_VERIFIED": { LOGIN_USER_NOT_VERIFIED: {
title: "Account not verified", title: "Account not verified",
description: "Please verify your email address before signing in" description: "Please verify your email address before signing in",
}, },
"USER_INACTIVE": { USER_INACTIVE: {
title: "Account inactive", title: "Account inactive",
description: "Your account has been deactivated. Contact support for assistance" description: "Your account has been deactivated. Contact support for assistance",
}, },
"REGISTER_USER_ALREADY_EXISTS": { REGISTER_USER_ALREADY_EXISTS: {
title: "Account already exists", title: "Account already exists",
description: "An account with this email address already exists" description: "An account with this email address already exists",
}, },
"REGISTER_INVALID_PASSWORD": { REGISTER_INVALID_PASSWORD: {
title: "Invalid password", title: "Invalid password",
description: "Password must meet security requirements" description: "Password must meet security requirements",
}, },
// OAuth errors // OAuth errors
"access_denied": { access_denied: {
title: "Access denied", title: "Access denied",
description: "You denied access or cancelled the login process" description: "You denied access or cancelled the login process",
}, },
"invalid_request": { invalid_request: {
title: "Invalid request", title: "Invalid request",
description: "The login request was malformed" description: "The login request was malformed",
}, },
"unauthorized_client": { unauthorized_client: {
title: "Authentication failed", title: "Authentication failed",
description: "The application is not authorized to perform this action" description: "The application is not authorized to perform this action",
}, },
"unsupported_response_type": { unsupported_response_type: {
title: "Login method not supported", title: "Login method not supported",
description: "This login method is not currently available" description: "This login method is not currently available",
}, },
"invalid_scope": { invalid_scope: {
title: "Invalid permissions", title: "Invalid permissions",
description: "The requested permissions are not valid" description: "The requested permissions are not valid",
}, },
"server_error": { server_error: {
title: "Server error", title: "Server error",
description: "An error occurred on the authentication server" description: "An error occurred on the authentication server",
}, },
"temporarily_unavailable": { temporarily_unavailable: {
title: "Service unavailable", title: "Service unavailable",
description: "Login is temporarily unavailable. Please try again later" description: "Login is temporarily unavailable. Please try again later",
}, },
// Network errors // Network errors
"NETWORK_ERROR": { NETWORK_ERROR: {
title: "Connection failed", title: "Connection failed",
description: "Please check your internet connection and try again" description: "Please check your internet connection and try again",
}, },
"TIMEOUT": { TIMEOUT: {
title: "Request timeout", title: "Request timeout",
description: "The login request took too long. Please try again" description: "The login request took too long. Please try again",
}, },
// Generic fallbacks // Generic fallbacks
"UNKNOWN_ERROR": { UNKNOWN_ERROR: {
title: "Login failed", title: "Login failed",
description: "An unexpected error occurred. Please try again" description: "An unexpected error occurred. Please try again",
} },
}; };
/** /**
@ -116,51 +116,51 @@ const AUTH_ERROR_MESSAGES: AuthErrorMapping = {
* @returns Formatted error message * @returns Formatted error message
*/ */
export function getAuthErrorMessage(errorCode: string, returnTitle: boolean = false): string { export function getAuthErrorMessage(errorCode: string, returnTitle: boolean = false): string {
if (!errorCode) { if (!errorCode) {
const fallback = AUTH_ERROR_MESSAGES.UNKNOWN_ERROR; const fallback = AUTH_ERROR_MESSAGES.UNKNOWN_ERROR;
return returnTitle ? fallback.title : fallback.description || fallback.title; return returnTitle ? fallback.title : fallback.description || fallback.title;
} }
// Clean up the error code // Clean up the error code
const cleanErrorCode = errorCode.trim().toUpperCase(); const cleanErrorCode = errorCode.trim().toUpperCase();
// Try exact match first
let errorInfo = AUTH_ERROR_MESSAGES[cleanErrorCode] || AUTH_ERROR_MESSAGES[errorCode];
// Try partial matches for HTTP status codes
if (!errorInfo) {
const statusCodeMatch = errorCode.match(/(\d{3})/);
if (statusCodeMatch) {
errorInfo = AUTH_ERROR_MESSAGES[statusCodeMatch[1]];
}
}
// Try partial matches for common error patterns
if (!errorInfo) {
const patterns = [
{ pattern: /credential|password|email/i, code: "LOGIN_BAD_CREDENTIALS" },
{ pattern: /verify|verification/i, code: "LOGIN_USER_NOT_VERIFIED" },
{ pattern: /inactive|disabled|suspended/i, code: "USER_INACTIVE" },
{ pattern: /exists|duplicate/i, code: "REGISTER_USER_ALREADY_EXISTS" },
{ pattern: /network|connection/i, code: "NETWORK_ERROR" },
{ pattern: /timeout/i, code: "TIMEOUT" },
{ pattern: /rate|limit|many/i, code: "429" },
];
for (const { pattern, code } of patterns) { // Try exact match first
if (pattern.test(errorCode)) { let errorInfo = AUTH_ERROR_MESSAGES[cleanErrorCode] || AUTH_ERROR_MESSAGES[errorCode];
errorInfo = AUTH_ERROR_MESSAGES[code];
break; // Try partial matches for HTTP status codes
} if (!errorInfo) {
} const statusCodeMatch = errorCode.match(/(\d{3})/);
} if (statusCodeMatch) {
errorInfo = AUTH_ERROR_MESSAGES[statusCodeMatch[1]];
// Fallback to unknown error }
if (!errorInfo) { }
errorInfo = AUTH_ERROR_MESSAGES.UNKNOWN_ERROR;
} // Try partial matches for common error patterns
if (!errorInfo) {
return returnTitle ? errorInfo.title : errorInfo.description || errorInfo.title; const patterns = [
{ pattern: /credential|password|email/i, code: "LOGIN_BAD_CREDENTIALS" },
{ pattern: /verify|verification/i, code: "LOGIN_USER_NOT_VERIFIED" },
{ pattern: /inactive|disabled|suspended/i, code: "USER_INACTIVE" },
{ pattern: /exists|duplicate/i, code: "REGISTER_USER_ALREADY_EXISTS" },
{ pattern: /network|connection/i, code: "NETWORK_ERROR" },
{ pattern: /timeout/i, code: "TIMEOUT" },
{ pattern: /rate|limit|many/i, code: "429" },
];
for (const { pattern, code } of patterns) {
if (pattern.test(errorCode)) {
errorInfo = AUTH_ERROR_MESSAGES[code];
break;
}
}
}
// Fallback to unknown error
if (!errorInfo) {
errorInfo = AUTH_ERROR_MESSAGES.UNKNOWN_ERROR;
}
return returnTitle ? errorInfo.title : errorInfo.description || errorInfo.title;
} }
/** /**
@ -169,10 +169,10 @@ export function getAuthErrorMessage(errorCode: string, returnTitle: boolean = fa
* @returns Object with title and description * @returns Object with title and description
*/ */
export function getAuthErrorDetails(errorCode: string): { title: string; description: string } { export function getAuthErrorDetails(errorCode: string): { title: string; description: string } {
const title = getAuthErrorMessage(errorCode, true); const title = getAuthErrorMessage(errorCode, true);
const description = getAuthErrorMessage(errorCode, false); const description = getAuthErrorMessage(errorCode, false);
return { title, description }; return { title, description };
} }
/** /**
@ -181,15 +181,15 @@ export function getAuthErrorDetails(errorCode: string): { title: string; descrip
* @returns True if it's a network error * @returns True if it's a network error
*/ */
export function isNetworkError(error: unknown): boolean { export function isNetworkError(error: unknown): boolean {
if (error instanceof TypeError && error.message.includes('fetch')) { if (error instanceof TypeError && error.message.includes("fetch")) {
return true; return true;
} }
if (typeof error === 'string') { if (typeof error === "string") {
return /network|connection|fetch|cors/i.test(error); return /network|connection|fetch|cors/i.test(error);
} }
return false; return false;
} }
/** /**
@ -198,10 +198,17 @@ export function isNetworkError(error: unknown): boolean {
* @returns True if retry is recommended * @returns True if retry is recommended
*/ */
export function shouldRetry(errorCode: string): boolean { export function shouldRetry(errorCode: string): boolean {
const retryableCodes = ['500', '503', '429', 'NETWORK_ERROR', 'TIMEOUT', 'server_error', 'temporarily_unavailable']; const retryableCodes = [
"500",
return retryableCodes.some(code => "503",
errorCode.includes(code) || "429",
errorCode.toUpperCase().includes(code) "NETWORK_ERROR",
); "TIMEOUT",
"server_error",
"temporarily_unavailable",
];
return retryableCodes.some(
(code) => errorCode.includes(code) || errorCode.toUpperCase().includes(code)
);
} }