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:
2026-02-06 22:25:04 +01:00
parent cfe6384f75
commit 3cac486f6f
2 changed files with 75 additions and 21 deletions

View File

@@ -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,

View File

@@ -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);