Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5809291741 | ||
|
|
e263e7f25c | ||
|
|
1fee592ee7 |
@@ -45,6 +45,28 @@ export async function sendContactFormAction(formData: FormData) {
|
||||
email,
|
||||
});
|
||||
|
||||
// 1.5. Simple Fail-Safe Backup to Disk
|
||||
// To ensure leads are never lost if email fails or Gotify is down, we append them to a local JSON Lines file.
|
||||
try {
|
||||
const fs = await import('fs');
|
||||
const path = await import('path');
|
||||
const backupDir = path.join(process.cwd(), '.data');
|
||||
if (!fs.existsSync(backupDir)) fs.mkdirSync(backupDir, { recursive: true });
|
||||
|
||||
const backupFile = path.join(backupDir, 'leads-backup.jsonl');
|
||||
const leadData = {
|
||||
timestamp: new Date().toISOString(),
|
||||
name,
|
||||
email,
|
||||
productName,
|
||||
message,
|
||||
};
|
||||
fs.appendFileSync(backupFile, JSON.stringify(leadData) + '\\n');
|
||||
logger.info('Successfully saved lead to local backup file', { backupFile });
|
||||
} catch (backupError) {
|
||||
logger.error('Failed to write to local leads backup', { error: String(backupError) });
|
||||
}
|
||||
|
||||
// 2. Send Emails
|
||||
logger.info('Sending branded emails', { email, productName });
|
||||
|
||||
|
||||
+1
-1
@@ -113,7 +113,7 @@
|
||||
"prepare": "husky",
|
||||
"preinstall": "npx only-allow pnpm"
|
||||
},
|
||||
"version": "2.3.22-rc.10",
|
||||
"version": "2.3.22-rc.11",
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
"@parcel/watcher",
|
||||
|
||||
+22
-8
@@ -34,16 +34,30 @@ async function run() {
|
||||
const res = await page.goto(`${targetUrl}${p}`, { waitUntil: 'domcontentloaded' });
|
||||
if (res?.status() !== 200) throw new Error(`Page ${p} returned ${res?.status()}`);
|
||||
|
||||
// Check for broken images on this page
|
||||
const images = await page.$$eval('img', (imgs) => imgs.map((img) => img.src));
|
||||
// Check for broken images (using in-page fetch to preserve session and avoid heavy navigation)
|
||||
const images = await page.$$eval('img', (imgs) => imgs.map((img) => img.src).filter(Boolean));
|
||||
console.log(` Checking ${images.length} images...`);
|
||||
for (const src of images.slice(0, 5)) {
|
||||
// Check first 5 images per page
|
||||
const imgRes = await page.goto(src, { waitUntil: 'domcontentloaded' }).catch(() => null);
|
||||
if (imgRes && imgRes.status() >= 400)
|
||||
console.warn(` ⚠️ Broken image: ${src} (${imgRes.status()})`);
|
||||
|
||||
const brokenImages = await page.evaluate(async (urls) => {
|
||||
const broken: string[] = [];
|
||||
await Promise.all(
|
||||
urls.map(async (url) => {
|
||||
try {
|
||||
const res = await fetch(url, { method: 'HEAD' });
|
||||
if (res.status >= 400) broken.push(`${url} (Status: ${res.status})`);
|
||||
} catch (e) {
|
||||
broken.push(`${url} (Fetch failed)`);
|
||||
}
|
||||
}),
|
||||
);
|
||||
return broken;
|
||||
}, images);
|
||||
|
||||
if (brokenImages.length > 0) {
|
||||
throw new Error(
|
||||
`Found ${brokenImages.length} broken images on ${p}:\n${brokenImages.join('\n')}`,
|
||||
);
|
||||
}
|
||||
await page.goto(`${targetUrl}${p}`, { waitUntil: 'domcontentloaded' }); // Go back
|
||||
}
|
||||
|
||||
// 3. Test Contact Form
|
||||
|
||||
Reference in New Issue
Block a user