fix Steam API: transform response format and add comprehensive logging
- Backend: transform Steam API response to match frontend expectations (games/count structure) - Frontend: map Steam game fields (appid, name, playtime_forever) to database schema (id, title, playtimeHours) - Add detailed logging throughout request lifecycle for debugging - Add 60-second timeout with AbortController to prevent indefinite hanging - Fix IndexedDB constraint violation by properly transforming game data before save Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -23,9 +23,10 @@ app.get("/health", (req, res) => {
|
||||
app.post("/steam/refresh", async (req, res) => {
|
||||
const { apiKey, steamId } = req.body;
|
||||
|
||||
console.log(`Steam refresh for user: ${steamId}`);
|
||||
console.log(`[Steam] Starting refresh for user: ${steamId}`);
|
||||
|
||||
if (!apiKey || !steamId) {
|
||||
console.log("[Steam] Missing credentials");
|
||||
return res.status(400).json({
|
||||
error: "Missing required fields: apiKey and steamId",
|
||||
});
|
||||
@@ -35,9 +36,12 @@ app.post("/steam/refresh", async (req, res) => {
|
||||
// Call Steam Web API
|
||||
const steamUrl = `https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/?key=${apiKey}&steamid=${steamId}&include_appinfo=1&include_played_free_games=1&format=json`;
|
||||
|
||||
console.log("[Steam] Calling Steam API...");
|
||||
const response = await fetch(steamUrl);
|
||||
console.log(`[Steam] Got response: ${response.status}`);
|
||||
|
||||
if (!response.ok) {
|
||||
console.log(`[Steam] Steam API error: ${response.statusText}`);
|
||||
return res.status(response.status).json({
|
||||
error: "Steam API error",
|
||||
message: response.statusText,
|
||||
@@ -45,9 +49,20 @@ app.post("/steam/refresh", async (req, res) => {
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
res.json(data);
|
||||
console.log(`[Steam] Success! Games count: ${data.response?.game_count || 0}`);
|
||||
|
||||
// Transform Steam API response to match frontend expectations
|
||||
const transformed = {
|
||||
games: data.response?.games || [],
|
||||
count: data.response?.game_count || 0,
|
||||
};
|
||||
|
||||
const responseSize = JSON.stringify(transformed).length;
|
||||
console.log(`[Steam] Sending response: ${responseSize} bytes, ${transformed.games.length} games`);
|
||||
res.json(transformed);
|
||||
console.log(`[Steam] Response sent successfully`);
|
||||
} catch (error) {
|
||||
console.error("Steam API error:", error);
|
||||
console.error("[Steam] Exception:", error);
|
||||
res.status(500).json({
|
||||
error: "Failed to fetch games",
|
||||
message: error.message,
|
||||
|
||||
@@ -122,28 +122,65 @@ export default function SettingsDetailPage() {
|
||||
}
|
||||
|
||||
const apiUrl = ConfigService.getApiUrl("/api/steam/refresh");
|
||||
const response = await fetch(apiUrl, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
apiKey: steamConfig.apiKey,
|
||||
steamId: steamConfig.steamId,
|
||||
}),
|
||||
});
|
||||
console.log("[Frontend] Calling Steam API:", apiUrl);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
setApiOutput(`❌ API Fehler: ${response.status}\n${errorText}`);
|
||||
setAlertMessage("Steam Refresh fehlgeschlagen");
|
||||
setShowAlert(true);
|
||||
return;
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), 60000); // 60 second timeout
|
||||
|
||||
try {
|
||||
const response = await fetch(apiUrl, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
apiKey: steamConfig.apiKey,
|
||||
steamId: steamConfig.steamId,
|
||||
}),
|
||||
signal: controller.signal,
|
||||
});
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
console.log("[Frontend] Got response:", response.status, response.statusText);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error("[Frontend] API error:", errorText);
|
||||
setApiOutput(`❌ API Fehler: ${response.status}\n${errorText}`);
|
||||
setAlertMessage("Steam Refresh fehlgeschlagen");
|
||||
setShowAlert(true);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("[Frontend] Parsing JSON response...");
|
||||
result = await response.json();
|
||||
console.log("[Frontend] Parsed result:", {
|
||||
count: result.count,
|
||||
gamesLength: result.games?.length,
|
||||
});
|
||||
} catch (fetchError) {
|
||||
clearTimeout(timeoutId);
|
||||
if (fetchError.name === 'AbortError') {
|
||||
throw new Error('Request timeout - Steam API took too long to respond');
|
||||
}
|
||||
throw fetchError;
|
||||
}
|
||||
|
||||
result = await response.json();
|
||||
}
|
||||
|
||||
if (result) {
|
||||
await db.saveGames(result.games);
|
||||
console.log("[Frontend] Saving games to database...");
|
||||
|
||||
// Transform Steam games to match our Game interface
|
||||
const transformedGames = result.games.map((steamGame: any) => ({
|
||||
id: `steam-${steamGame.appid}`,
|
||||
title: steamGame.name,
|
||||
source: 'steam',
|
||||
sourceId: String(steamGame.appid),
|
||||
platform: 'steam',
|
||||
playtimeHours: steamGame.playtime_forever ? Math.round(steamGame.playtime_forever / 60) : 0,
|
||||
url: `https://store.steampowered.com/app/${steamGame.appid}`,
|
||||
}));
|
||||
|
||||
await db.saveGames(transformedGames);
|
||||
console.log("[Frontend] Games saved successfully");
|
||||
|
||||
const updatedConfig = {
|
||||
...config,
|
||||
@@ -155,14 +192,16 @@ export default function SettingsDetailPage() {
|
||||
setConfig(updatedConfig);
|
||||
await ConfigService.saveConfig(updatedConfig);
|
||||
|
||||
console.log("[Frontend] Update complete, showing results");
|
||||
setApiOutput(
|
||||
`✓ ${result.count} Spiele abgerufen\n\nBeispiel:\n${JSON.stringify(result.games.slice(0, 2), null, 2)}`,
|
||||
`✓ ${result.count} Spiele abgerufen\n\nBeispiel:\n${JSON.stringify(transformedGames.slice(0, 2), null, 2)}`,
|
||||
);
|
||||
setAlertMessage(`✓ ${result.count} Spiele aktualisiert`);
|
||||
setShowAlert(true);
|
||||
}
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : String(error);
|
||||
console.error("[Frontend] Error during refresh:", error);
|
||||
setApiOutput(`❌ Fehler: ${errorMsg}`);
|
||||
setAlertMessage("Aktualisierung fehlgeschlagen");
|
||||
setShowAlert(true);
|
||||
|
||||
Reference in New Issue
Block a user