The page reports its errors and playback timings, and its requests carry a trace (#190)
Nothing the page did in the browser reached the logs: a DeadAir playback failure on the phone was a toast and nothing more. POST /api/client takes page errors, unhandled rejections, hls.js and media errors, the time from play to sound and the length of a stall, and logs them as ev lines under ipx::client, inside the request's span. Only those kinds are taken, the text cut to 500 characters, and the page sends each at most once a minute. The page's API requests send traceparent, a new trace id for each tap or key, and the server's request span takes it as its parent, so one action's requests are one trace in Tempo, the report included. The stub DOM the smoke and native-bridge tests run in gains crypto and performance, which every browser the page runs in has. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -27,7 +27,8 @@ function setSrc(url: string): Promise<void>|null{
|
||||
});
|
||||
return ready.then(()=>{
|
||||
hls=new w.Hls();
|
||||
hls.on(w.Hls.Events.ERROR,(_,d)=>{ if(d.fatal) toast('Playback failed: '+d.details,true); });
|
||||
hls.on(w.Hls.Events.ERROR,(_,d)=>{ if(d.fatal){ toast('Playback failed: '+d.details,true);
|
||||
report('player_error',{msg:`hls.js: ${d.type} ${d.details}`,feed:player.feed,enclosure:player.enc}); } });
|
||||
hls.loadSource(url); hls.attachMedia(audio);
|
||||
});
|
||||
}
|
||||
@@ -137,6 +138,20 @@ function syncPlayButtons(){
|
||||
}
|
||||
for(const ev of ['play','pause','timeupdate']) audio.addEventListener(ev,syncListening);
|
||||
window.addEventListener('beforeunload',savePos);
|
||||
|
||||
/// For the server's log (#190): how long play takes to start, how long it stalls for, and what
|
||||
/// the browser says when it cannot play a file at all.
|
||||
let asked=0, waited=0;
|
||||
const playing=()=>({feed:player.feed,enclosure:player.enc,deadair:!!player.src?.endsWith('.m3u8')});
|
||||
audio.addEventListener('play',()=>{ asked=performance.now(); });
|
||||
audio.addEventListener('waiting',()=>{ if(!asked) waited=performance.now(); });
|
||||
audio.addEventListener('playing',()=>{
|
||||
const now=performance.now();
|
||||
if(asked) report('play_start',{ms:Math.round(now-asked),...playing()});
|
||||
else if(waited && now-waited>=500) report('stall',{ms:Math.round(now-waited),...playing()});
|
||||
asked=0; waited=0;
|
||||
});
|
||||
audio.addEventListener('error',()=>{ if(audio.error) report('player_error',{msg:`media error ${audio.error.code}: ${audio.error.message}`,...playing()}); });
|
||||
$('#pplay').onclick=()=>audio.paused?audio.play():audio.pause();
|
||||
$('#pback').onclick=()=>audio.currentTime-=15;
|
||||
$('#pfwd').onclick=()=>audio.currentTime+=30;
|
||||
|
||||
Reference in New Issue
Block a user