Click redirect handlers sit in the path between every tracked link in your emails and the page the recipient is trying to reach. When tracking logic throws an unhandled exception — a database timeout, a network blip, a missing link ID — and the redirect doesn't fire, the user hits a 500 error instead of your landing page. Every tracked link in every sent email becomes a broken link for the duration of the outage. This is an iso-25010:2011 reliability failure: the observability instrumentation should never degrade the user's ability to navigate to the destination URL.
High because a tracking write failure converts every email link into a broken link for the user, destroying the campaign's conversion path and damaging sender reputation in a way that affects every recipient simultaneously.
Wrap all tracking logic in a try/catch and fire the tracking write as a detached promise so a DB failure never blocks the redirect. Set a safe fallback URL before the try block:
export async function GET(req: Request, { params }: { params: { token: string } }) {
let destinationUrl = 'https://yourdomain.com' // fallback — never leave this blank
try {
const link = await db.trackedLinks.findUnique({ where: { token: params.token } })
if (link) {
destinationUrl = link.original_url
// Fire-and-forget — do not await in the redirect path
db.clickEvents.create({
data: { link_id: link.id, campaign_id: link.campaign_id, occurred_at: new Date() }
}).catch((err) => console.error('Click tracking write failed:', err))
}
} catch (err) {
console.error('Click redirect error:', err)
// destinationUrl already set to fallback above
}
return Response.redirect(destinationUrl, 302)
}
Handle the missing-link-ID case explicitly — either redirect to a documented fallback URL or return a 404 with a helpful message, never a bare 500.
ID: campaign-analytics-attribution.tracking-implementation.click-redirect-fallback
Severity: high
What to look for: Examine the click redirect route handler. Trace the code path when the tracking record or database write fails — does the redirect still occur to the original URL, or does the user see an error page? Look for try/catch blocks around the tracking logic, and verify that the redirect to the destination URL happens regardless of whether the tracking write succeeds. Check for cases where the destination URL lookup itself might fail (e.g., the link ID is not found in the database — does this return a 404 or redirect to a safe fallback?).
Pass criteria: The redirect to the original URL occurs even if the tracking database write fails. If the link ID is not found, either a safe fallback URL is used or a 404 with a meaningful error page is shown. The click tracking failure does not break the user's navigation. List all error-handling paths in the redirect handler and count the fallback redirects — at least 1 must cover database failure and at least 1 must cover a missing link ID.
Fail criteria: An exception in tracking logic is not caught, causing the redirect to fail with a 500 error. Or the user sees an error page when the link ID is not found, with no fallback URL. Having a try/catch that logs the error but does not redirect the user does not count as pass.
Skip (N/A) when: The project does not implement click redirect tracking.
Detail on fail: Example: "Click redirect throws unhandled exception on DB failure — users would see 500 error instead of being redirected" or "No try/catch around tracking write — any DB timeout blocks the redirect"
Remediation: Always redirect regardless of tracking outcome:
export async function GET(req: Request, { params }: { params: { token: string } }) {
let destinationUrl = 'https://yourdomain.com' // safe fallback
try {
const link = await db.trackedLinks.findUnique({ where: { token: params.token } })
if (link) {
destinationUrl = link.original_url
// Fire-and-forget tracking write — do not await in the redirect path
db.clickEvents.create({
data: {
link_id: link.id,
campaign_id: link.campaign_id,
contact_id: extractContactId(req),
occurred_at: new Date()
}
}).catch((err) => console.error('Click tracking write failed:', err))
}
} catch (err) {
console.error('Click redirect tracking error:', err)
// destinationUrl remains as fallback — user still reaches a page
}
return Response.redirect(destinationUrl, 302)
}