From bba9a1a228376e84df33212df66bafd7fa0790b3 Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Thu, 10 Sep 2026 15:54:58 -0400 Subject: [PATCH 1/3] Handle prefixed Twitter handles during show import --- src/server/shows.ts | 50 +++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/server/shows.ts b/src/server/shows.ts index 90b515266..d1142489c 100644 --- a/src/server/shows.ts +++ b/src/server/shows.ts @@ -23,11 +23,15 @@ export async function import_or_update_all_shows() { // Read and process each .md file for (const md_file_path in md_files) { - const { number, hash, md_file_contents } = await get_show_data_from_glob( - md_files[md_file_path], - md_file_path - ); - await parse_and_save_show_notes(md_file_contents, hash, number, md_file_path); + try { + const { number, hash, md_file_contents } = await get_show_data_from_glob( + md_files[md_file_path], + md_file_path + ); + await parse_and_save_show_notes(md_file_contents, hash, number, md_file_path); + } catch (err) { + throw new Error(`Failed to import ${md_file_path}`, { cause: err }); + } } } catch (err) { console.error('❌ Pod Sync Error:', err); @@ -46,10 +50,17 @@ export async function import_or_update_all_changed_shows() { // Read and process each .md file for (const md_file_path in md_files) { - const { number, hash, md_file_contents } = await get_show_data_from_glob( - md_files[md_file_path], - md_file_path - ); + let number: number; + let hash: string; + let md_file_contents: string; + try { + ({ number, hash, md_file_contents } = await get_show_data_from_glob( + md_files[md_file_path], + md_file_path + )); + } catch (err) { + throw new Error(`Failed to import ${md_file_path}`, { cause: err }); + } const existing_show = await prisma.show.findUnique({ where: { number: number } @@ -80,8 +91,11 @@ export async function import_or_update_all_changed_shows() { async function get_show_data_from_glob(md_file_contents: string, md_file_path: string) { const hash = await get_hash_from_content(md_file_contents); - const cleaned_path = md_file_path.replace('/shows/', ''); - const number = parseInt(cleaned_path.split(' - ')[0]); + const filename = md_file_path.split('/').pop() ?? ''; + const number = parseInt(filename, 10); + if (Number.isNaN(number)) { + throw new Error(`Could not determine show number from ${md_file_path}`); + } return { number, hash, md_file_contents }; } @@ -93,7 +107,9 @@ export async function parse_and_save_show_notes( md_file: string ) { // Parse the front matter - const { data, content } = matter(notes); + // YAML treats an unquoted @ as invalid, even though it is a common handle format. + const parseable_notes = notes.replace(/^(\s*twitter:\s*)@([^\s#]+)(\s*(?:#.*)?)$/gm, '$1$2$3'); + const { data, content } = matter(parseable_notes); const date = new Date(data.date); // Parse the date string into a Date object @@ -104,13 +120,14 @@ export async function parse_and_save_show_notes( DAYS_OF_WEEK_TYPES[dayOfWeek] || 'SPECIAL'; // Save or update the show try { - // Prepare the hosts connection if hosts exist in the frontmatter + // Accept both spellings because older and newer show files use different casing. + const hosts = data.hosts ?? data.Hosts; let hostsConnection = {}; - if (data.hosts && Array.isArray(data.hosts)) { + if (hosts && Array.isArray(hosts)) { const hostUsers = await prisma.user.findMany({ where: { username: { - in: data.hosts + in: hosts } } }); @@ -180,6 +197,9 @@ export async function parse_and_save_show_notes( async function add_or_update_guest(guest: FrontMatterGuest, show_id: string) { try { const { social, name, ...guest_without_socials } = guest; + if (typeof guest_without_socials.twitter === 'string') { + guest_without_socials.twitter = guest_without_socials.twitter.replace(/^@/, ''); + } const name_slug = slug(name); const guest_record = await prisma.$transaction(async (prisma) => { From f2e52082bf2088f3fada909f934c1da2ce2f3f9e Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Thu, 10 Sep 2026 15:55:11 -0400 Subject: [PATCH 2/3] Report show import failures to Sentry --- src/server/shows.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/server/shows.ts b/src/server/shows.ts index d1142489c..6f337b22b 100644 --- a/src/server/shows.ts +++ b/src/server/shows.ts @@ -5,6 +5,7 @@ import { left_pad } from '$utilities/left_pad'; import { error } from '@sveltejs/kit'; import matter from 'gray-matter'; import slug from 'speakingurl'; +import * as Sentry from '@sentry/sveltekit'; import { prisma_client as prisma } from '$/server/prisma-client'; import { cache } from './cache/cache'; @@ -35,6 +36,7 @@ export async function import_or_update_all_shows() { } } catch (err) { console.error('❌ Pod Sync Error:', err); + Sentry.captureException(err); error(500, 'Error Importing Shows'); } console.log('🤖 Pod Sync Complete ✅'); @@ -82,6 +84,7 @@ export async function import_or_update_all_changed_shows() { } } catch (err) { console.error('❌ Pod Sync Error:', err); + Sentry.captureException(err); error(500, 'Error Importing Shows'); } cache.shows.drop_shows_list_cache(); From 4c76296d772ee2d5c8c93053476f62e9769bd58f Mon Sep 17 00:00:00 2001 From: Wes Bos Date: Thu, 10 Sep 2026 15:59:09 -0400 Subject: [PATCH 3/3] Reject invalid capitalized hosts metadata --- src/server/shows.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/server/shows.ts b/src/server/shows.ts index 6f337b22b..183da8315 100644 --- a/src/server/shows.ts +++ b/src/server/shows.ts @@ -123,8 +123,7 @@ export async function parse_and_save_show_notes( DAYS_OF_WEEK_TYPES[dayOfWeek] || 'SPECIAL'; // Save or update the show try { - // Accept both spellings because older and newer show files use different casing. - const hosts = data.hosts ?? data.Hosts; + const hosts = data.hosts; let hostsConnection = {}; if (hosts && Array.isArray(hosts)) { const hostUsers = await prisma.user.findMany({