Files
noteflow/src/services/OpenRouterService.ts
T
Claude f8cef758ad Fix: Amélioration des logs et gestion d'erreurs pour l'assistant IA OpenRouter
Problème :
- Erreur 502 (Bad Gateway) sur /api/openrouter/chat
- Message d'erreur générique "Provider returned error" peu informatif
- Difficile de diagnostiquer la cause réelle du problème

Solution backend (routes/openrouter.routes.js) :
1. Ajout de logs détaillés à chaque étape :
   - Début de requête avec modèle et nombre de messages
   - Validation de la clé API
   - Requête envoyée à OpenRouter
   - Réponse reçue avec status HTTP
   - Contenu de la réponse ou erreur détaillée

2. Amélioration de la gestion des erreurs :
   - Extraction du message d'erreur d'OpenRouter
   - Logs structurés avec contexte complet
   - Messages d'erreur plus descriptifs

Solution frontend (src/services/OpenRouterService.ts) :
1. Ajout de logs console à chaque étape
2. Messages d'erreur contextuels selon le code HTTP :
   - 400 : Requête invalide (message d'erreur API)
   - 401 : Clé API invalide
   - 402 : Crédits épuisés
   - 429 : Trop de requêtes
   - 502/503 : Service temporairement indisponible

3. Validation de la réponse :
   - Vérification que le contenu existe
   - Message d'erreur si réponse vide

Résultat :
- Logs détaillés backend + frontend pour diagnostic
- Messages d'erreur clairs et actionnables pour l'utilisateur
- Meilleure traçabilité des problèmes OpenRouter
2025-11-18 10:40:43 +00:00

116 lines
3.6 KiB
TypeScript

import AuthService from './AuthService';
export interface OpenRouterModel {
id: string;
name: string;
description: string;
context_length: number;
pricing: {
prompt?: string;
completion?: string;
};
}
class OpenRouterService {
/**
* Get available models from OpenRouter API
*/
async getModels(): Promise<OpenRouterModel[]> {
try {
const response = await fetch('/api/openrouter/models', {
headers: AuthService.getHeaders()
});
if (!response.ok) {
throw new Error('Erreur lors de la récupération des modèles');
}
const models = await response.json();
return Array.isArray(models) ? models : [];
} catch (error) {
console.error('Erreur lors de la récupération des modèles OpenRouter:', error);
return [];
}
}
/**
* Refresh models cache
*/
async refreshModels(): Promise<OpenRouterModel[]> {
try {
const response = await fetch('/api/openrouter/refresh-models', {
method: 'POST',
headers: AuthService.getHeaders()
});
if (!response.ok) {
throw new Error('Erreur lors du rafraîchissement des modèles');
}
const data = await response.json();
return Array.isArray(data.models) ? data.models : [];
} catch (error) {
console.error('Erreur lors du rafraîchissement des modèles:', error);
throw error;
}
}
/**
* Send chat message to AI model
*/
async sendMessage(model: string, messages: Array<{ role: string; content: string }>): Promise<string> {
try {
console.log(`[OpenRouter] Envoi requête - model: ${model}, messages: ${messages.length}`);
const response = await fetch('/api/openrouter/chat', {
method: 'POST',
headers: {
...AuthService.getHeaders(),
'Content-Type': 'application/json'
},
body: JSON.stringify({ model, messages })
});
console.log(`[OpenRouter] Réponse reçue - status: ${response.status}`);
if (!response.ok) {
const errorData = await response.json().catch(() => ({ error: 'Erreur inconnue' }));
const errorMessage = errorData.error || `Erreur HTTP ${response.status}`;
console.error('[OpenRouter] Erreur:', errorMessage);
// Messages d'erreur plus clairs selon le code HTTP
if (response.status === 400) {
throw new Error(errorMessage);
} else if (response.status === 401) {
throw new Error('Clé API invalide. Vérifiez la configuration dans Paramètres.');
} else if (response.status === 402) {
throw new Error('Crédits OpenRouter épuisés. Rechargez votre compte.');
} else if (response.status === 429) {
throw new Error('Trop de requêtes. Attendez quelques instants.');
} else if (response.status === 502 || response.status === 503) {
throw new Error('Service OpenRouter temporairement indisponible. Réessayez dans quelques instants.');
} else {
throw new Error(errorMessage);
}
}
const data = await response.json();
const content = data.choices?.[0]?.message?.content;
if (!content) {
console.error('[OpenRouter] Réponse vide:', data);
throw new Error('Aucune réponse générée par le modèle');
}
console.log(`[OpenRouter] Succès - ${content.length} caractères`);
return content;
} catch (error: any) {
console.error('[OpenRouter] Erreur exception:', error);
throw error;
}
}
}
export default new OpenRouterService();