Reviews: a store read that failed everywhere is an error, not an empty fresh list; Reviews tab says Apple's API can lag and Play returns 7 days; pitfall 106
This commit is contained in:
parent
0e88e4293a
commit
75bf62e125
7 changed files with 50 additions and 8 deletions
|
|
@ -63,6 +63,19 @@ export function parsePlayReviews(resp: PlayReviewsResp): Review[] {
|
|||
});
|
||||
}
|
||||
|
||||
export interface StoreRead { store: 'apple' | 'play'; reviews?: Review[]; error?: string }
|
||||
|
||||
/**
|
||||
* Combines the per-store reads of `reviews list`. A store that failed is reported (warning text per store) but does not
|
||||
* hide the other one; when EVERY store that was asked failed it throws, so a broken key never reads as "0 reviews, all
|
||||
* fine" (the desktop kept such an empty result as a fresh read and showed no new reviews).
|
||||
*/
|
||||
export function settleStoreReads(reads: StoreRead[]): { reviews: Review[]; errors: string[] } {
|
||||
const errors = reads.filter(r => r.error !== undefined).map(r => `${r.store}: ${r.error}`);
|
||||
if (reads.length && errors.length === reads.length) throw new Error(errors.join('; '));
|
||||
return { reviews: reads.flatMap(r => r.reviews ?? []), errors };
|
||||
}
|
||||
|
||||
/** Reviews newer than `sinceIso`, optional filters, newest first. */
|
||||
export function filterReviews(rs: Review[], o: { since?: string; unanswered?: boolean; ratings?: number[] } = {}): Review[] {
|
||||
return rs.filter(r => (!o.since || r.date >= o.since) && (!o.unanswered || !r.reply) && (!o.ratings?.length || o.ratings.includes(r.rating)))
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import { confirm } from './lib/ctx';
|
|||
import { done, log, printJson, warn } from './lib/log';
|
||||
import {
|
||||
checkReply, type Draft, draftMarkdown, draftName, filterReviews, markSent, parseAppleReviews, parseDraft, parsePlayReviews, replyRequest,
|
||||
type Review, sendPlan,
|
||||
type Review, sendPlan, settleStoreReads, type StoreRead,
|
||||
} from './lib/reviews';
|
||||
import { textTable } from './lib/table';
|
||||
import { readReplyDrafts, setApproved, setReplyText } from './lib/project-files';
|
||||
|
|
@ -63,13 +63,13 @@ async function collect(ctx: Ctx, o: { since: string; unanswered: boolean; rating
|
|||
const { config } = ctx.loaded;
|
||||
const store = ctx.args.get('store');
|
||||
if (store && store !== 'apple' && store !== 'play') throw new Error('--store apple | play');
|
||||
const all: Review[] = [];
|
||||
if ((!store || store === 'apple') && config.apple) {
|
||||
try { all.push(...await appleReviews(ctx, o.since)); } catch (e) { if (store) throw e; warn(TAG, `apple: ${(e as Error).message.slice(0, 200)}`); }
|
||||
}
|
||||
if ((!store || store === 'play') && config.play) {
|
||||
try { all.push(...await playReviews(ctx)); } catch (e) { if (store) throw e; warn(TAG, `play: ${(e as Error).message.slice(0, 200)}`); }
|
||||
const reads: StoreRead[] = [];
|
||||
for (const [name, on, read] of [['apple', !!config.apple, () => appleReviews(ctx, o.since)], ['play', !!config.play, () => playReviews(ctx)]] as const) {
|
||||
if (store && store !== name || !on) continue;
|
||||
try { reads.push({ store: name, reviews: await read() }); } catch (e) { if (store) throw e; reads.push({ store: name, error: (e as Error).message.slice(0, 200) }); }
|
||||
}
|
||||
const { reviews: all, errors } = settleStoreReads(reads);
|
||||
for (const e of errors) warn(TAG, e);
|
||||
return filterReviews(all, o);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue