fix: hardcode tenant list as fallback (API returns 403), add verbose error logging

This commit is contained in:
Martin Porwoll 2026-03-01 10:11:13 +00:00
parent f93fe9a6a0
commit dc2179a4d6
3 changed files with 33 additions and 28 deletions

View file

@ -167,7 +167,8 @@ class PayloadClient {
try { try {
const response = await this.authFetch(`${this.apiUrl}/users/me`); const response = await this.authFetch(`${this.apiUrl}/users/me`);
return response.ok; return response.ok;
} catch { } catch (error) {
log.error('Health check failed', error);
return false; return false;
} }
} }

View file

@ -5,7 +5,7 @@ import { config } from '../config.js';
import { payloadClient } from '../payload/client.js'; import { payloadClient } from '../payload/client.js';
import { downloadFile } from '../utils/download.js'; import { downloadFile } from '../utils/download.js';
import { createLogger } from '../utils/logger.js'; import { createLogger } from '../utils/logger.js';
import { buildTenantKeyboard, getTenantName } from './keyboards.js'; import { buildTenantKeyboard, getTenantName, getTenantList } from './keyboards.js';
const log = createLogger('Handlers'); const log = createLogger('Handlers');
@ -203,15 +203,10 @@ async function processAlbum(
} }
async function buildAnleitung(): Promise<string> { async function buildAnleitung(): Promise<string> {
let tenantList = 'Tenants konnten nicht geladen werden\\.'; const tenants = await getTenantList();
try { const tenantList = tenants
const tenants = await payloadClient.listTenants();
tenantList = tenants
.map((t) => ` \`${t.id}\` \\${escapeMarkdown(t.name)}`) .map((t) => ` \`${t.id}\` \\${escapeMarkdown(t.name)}`)
.join('\n'); .join('\n');
} catch {
log.warn('Could not load tenants for Anleitung');
}
return ( return (
`📷 *Payload Media Upload Bot \\— Anleitung*\n\n` + `📷 *Payload Media Upload Bot \\— Anleitung*\n\n` +

View file

@ -4,8 +4,20 @@ import { createLogger } from '../utils/logger.js';
const log = createLogger('Keyboards'); const log = createLogger('Keyboards');
// Known tenants — hardcoded fallback since /api/tenants requires special access
const KNOWN_TENANTS: TenantDoc[] = [
{ id: 4, name: 'porwoll.de', slug: 'porwoll' },
{ id: 5, name: 'zytoskandal.de', slug: 'zytoskandal' },
{ id: 8, name: 'caroline-porwoll.de', slug: 'caroline-porwoll' },
{ id: 9, name: 'blogwoman.de', slug: 'blogwoman' },
{ id: 10, name: 'complexcaresolutions.de', slug: 'complexcaresolutions' },
{ id: 11, name: 'gunshin.de', slug: 'gunshin' },
{ id: 12, name: 'zweitmeinu.ng', slug: 'zweitmeinung' },
{ id: 13, name: 'sensualmoment.de', slug: 'sensualmoment' },
];
// Tenant cache with 5-minute TTL // Tenant cache with 5-minute TTL
let tenantCache: TenantDoc[] | null = null; let tenantCache: TenantDoc[] = KNOWN_TENANTS;
let cacheExpiresAt = 0; let cacheExpiresAt = 0;
const CACHE_TTL = 5 * 60 * 1000; // 5 minutes const CACHE_TTL = 5 * 60 * 1000; // 5 minutes
@ -13,7 +25,7 @@ async function loadTenants(): Promise<TenantDoc[]> {
const now = Date.now(); const now = Date.now();
// Return valid cache // Return valid cache
if (tenantCache && cacheExpiresAt > now) { if (cacheExpiresAt > now) {
return tenantCache; return tenantCache;
} }
@ -23,15 +35,12 @@ async function loadTenants(): Promise<TenantDoc[]> {
cacheExpiresAt = now + CACHE_TTL; cacheExpiresAt = now + CACHE_TTL;
log.info(`Loaded ${tenants.length} tenants from API`); log.info(`Loaded ${tenants.length} tenants from API`);
return tenants; return tenants;
} catch (error) { } catch {
// Stale cache fallback: if API fails but we have old data, return it // API access denied or failed — use hardcoded fallback
if (tenantCache) { cacheExpiresAt = now + CACHE_TTL;
log.warn('API failed, returning stale tenant cache', error); log.info('Using hardcoded tenant list (API returned 403)');
return tenantCache; return tenantCache;
} }
log.error('Failed to load tenants and no cache available', error);
throw error;
}
} }
export async function buildTenantKeyboard(): Promise<InlineKeyboard> { export async function buildTenantKeyboard(): Promise<InlineKeyboard> {
@ -51,11 +60,11 @@ export async function buildTenantKeyboard(): Promise<InlineKeyboard> {
} }
export async function getTenantName(tenantId: number): Promise<string> { export async function getTenantName(tenantId: number): Promise<string> {
try {
const tenants = await loadTenants(); const tenants = await loadTenants();
const tenant = tenants.find((t) => t.id === tenantId); const tenant = tenants.find((t) => t.id === tenantId);
return tenant?.name ?? `Tenant ${tenantId}`; return tenant?.name ?? `Tenant ${tenantId}`;
} catch {
return `Tenant ${tenantId}`;
} }
export async function getTenantList(): Promise<TenantDoc[]> {
return loadTenants();
} }