Ignore:
Timestamp:
08/10/2026 08:14:13 AM (4 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
86ec01b
Parents:
75f2897
Message:

De thread-melding wijst nu naar de juiste partij

Bart opende een post van boiert.eu en las "Replies could not be loaded from
your server" terwijl onze server het prima deed: de BRON weigerde. Het was een
friends-only post van een account dat hij 's ochtends nog volgde en nu niet
meer, en Klonkt geeft een niet-publieke note alleen aan followers -- boiert
weigerde dus terecht, met 404, ook op het ondertekende verzoek.

signedGetJson slikte die status ("if (!r.ok) return null"), dus getThread wist
niet WAAROM het misging en de route kon het niet zeggen. Nu geeft hij de status
door aan wie erom vraagt, en getThread draagt hem als sourceStatus.

De route splitst daarop: 401/403/404/410 is een besluit van die server (niet
gedeeld, of weg) en blijft 404 'not shared by source'; al het andere, inclusief
een status die we niet eens kregen, wordt 502 'source unreachable'. Zonder dat
onderscheid vervang je een verkeerde schuldige door een andere gok.

Co-Authored-By: Claude Opus 5 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/services/ActivityPubService.js

    r75f2897 raae5881  
    36983698  if (hit && Date.now() - hit.at < THREAD_VIEW_TTL_MS) return hit.out;
    36993699
    3700   const get = (u) => localNoteObject(u, slug) || signedGetJson(slug, u);
     3700  // De status waarmee de BRON antwoordde op de note zelf. 401/403/404/410 is
     3701  // een besluit van die server (niet gedeeld, of weg); alles daarbuiten -- ook
     3702  // een stuk netwerk dat wegviel -- is een storing. De route moet dat verschil
     3703  // kunnen zeggen, anders wijst de melding naar de verkeerde partij.
     3704  let sourceStatus = 0;
     3705  const get = (u) => localNoteObject(u, slug) || signedGetJson(slug, u, (st) => { sourceStatus = st; });
    37013706  const note = await get(objectUri);
    37023707  const repliesRef = note && note.replies;
     
    37813786  })).sort((a, b) => String(a.published || '').localeCompare(String(b.published || '')));
    37823787
    3783   const out = { notes, found: !!note };
     3788  const out = { notes, found: !!note, sourceStatus };
    37843789  threadViewCache.set(key, { at: Date.now(), out });
    37853790  if (threadViewCache.size > THREAD_VIEW_CACHE_MAX) {
     
    50015006 * (request-target) host date, the set verifyRequest checks.
    50025007 */
    5003 async function signedGetJson(slug, url) {
     5008async function signedGetJson(slug, url, onStatus) {
    50045009  try {
    50055010    const base = (process.env.PUBLIC_BASE_URL || '').replace(/\/+$/, '');
     
    50145019    const sig = `keyId="${me}#main-key",algorithm="rsa-sha256",headers="(request-target) host date",signature="${signature}"`;
    50155020    const r = await safeFetch(url, { headers: { Accept: 'application/activity+json', Date: date, Signature: sig } });
     5021    // De status doorgeven aan wie erom vroeg: null alleen zegt "het lukte
     5022    // niet", en dat is te weinig om een WEIGERING van een STORING te
     5023    // onderscheiden. Wie geen callback meegeeft merkt hier niets van.
     5024    if (typeof onStatus === 'function') onStatus(r.status);
    50165025    if (!r.ok) return null;
    50175026    const len = Number(r.headers.get('content-length') || 0);
Note: See TracChangeset for help on using the changeset viewer.