{"record":{"id":"025e9fcfcf927b2e","repo":"tonhowtf/omniget","slug":"hls-nao-e-suportado-neste-navegador","errorCode":null,"errorMessage":"HLS nao e suportado neste navegador","messagePattern":"HLS nao e suportado neste navegador","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"src/lib/study-music/hls-loader.svelte.ts","lineNumber":20,"sourceCode":"\nexport type HlsHandle = {\n  destroy: () => void;\n};\n\nexport async function attachHls(audio: HTMLAudioElement, m3u8Url: string): Promise<HlsHandle> {\n  if (audio.canPlayType(\"application/vnd.apple.mpegurl\") !== \"\") {\n    audio.src = m3u8Url;\n    return {\n      destroy: () => {\n        try {\n          audio.src = \"\";\n        } catch {}\n      },\n    };\n  }\n\n  if (!Hls.isSupported()) {\n    throw new Error(\"HLS nao e suportado neste navegador\");\n  }\n\n  const hls = new Hls({\n    enableWorker: false,\n    lowLatencyMode: false,\n  });\n  hls.loadSource(m3u8Url);\n  hls.attachMedia(audio);\n\n  return {\n    destroy: () => {\n      try {\n        hls.destroy();\n      } catch {}\n    },\n  };\n}\n","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src/lib/study-music/hls-loader.svelte.ts#L2-L38","documentation":"Raised by extract_graphql_media when the GraphQL result for a tweet is a tombstone whose reason is not NsfwLoggedOut and whose text is not age-restricted (e.g. suspended, deleted, or blocked tweets). The library maps any unexplained tombstone to the generic \"Post not available\" because the media cannot be extracted.","triggerScenarios":"extract_graphql_media encounters a tombstone entry with a reason other than \"NsfwLoggedOut\" (deleted post, suspended account, country-withheld content), so it falls through to the final Err(anyhow!(\"Post not available\")) after the age-restriction check.","commonSituations":"Fetching a tweet that was deleted between enqueue and fetch; the author's account was suspended; the tweet is withheld in the scraper's region; stale tweet_ids in a batch job producing repeated failures.","solutions":["Treat as a permanent skip: mark the tweet_id unavailable and continue the batch","Log the tombstone reason/text from the raw response to distinguish deleted vs suspended vs withheld","Re-check the tweet via the syndication endpoint before permanently discarding it","Remove the dead tweet_id from the queue to avoid re-hitting the error"],"exampleFix":"// before\nErr(anyhow!(\"Post not available\"))\n// after\nErr(TwitterError::Tombstone { tweet_id, reason: reason.to_string() }) // preserves why the post is gone","handlingStrategy":"try-catch","validationCode":"// Cheap existence probe before full media extraction\nconst r = await fetch(`https://syndication.twitter.com/srv/timeline-profile/screen-name/${author}`);\nif (!r.ok) throw new SkipError('tweet likely deleted or suspended');","typeGuard":"function isTombstone(result) {\n  return result?.__typename === 'TweetTombstone';\n}","tryCatchPattern":"match tweet.extract_graphql_media(id) {\n    Err(e) if e.to_string() == \"Post not available\" => mark_unavailable(id),\n    other => other,\n}","preventionTips":["Treat tombstoned tweets as permanently unavailable; do not retry indefinitely","Record the tombstone reason from the raw response for diagnostics","Purge deleted tweet_ids from work queues","Keep raw GraphQL responses for post-hoc triage of new tombstone reasons"],"tags":["twitter","tombstone","deleted-content","graphql"],"backgroundTag":"resource-not-found","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}