Skip to content

Coderabbit review - #8

Closed
smb060606 wants to merge 4 commits into
mainfrom
feat/user-auth-ui-improvements-review-2
Closed

Coderabbit review#8
smb060606 wants to merge 4 commits into
mainfrom
feat/user-auth-ui-improvements-review-2

Conversation

@smb060606

@smb060606 smb060606 commented Dec 10, 2025

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

Release Notes

  • New Features

    • Added user logout functionality with session clearing
    • Implemented session management for authenticated users
    • Added health status monitoring endpoint for system diagnostics
    • Enhanced error validation with descriptive messages across authentication flows
    • Improved UI error handling and loading states for better visibility
  • Documentation

    • Clarified eligibility criteria with explicit thresholds and platform-specific account age requirements
    • Updated transparency documentation on account selection across analysis phases

✏️ Tip: You can customize this high-level summary in your review settings.

sahilm2002 and others added 4 commits December 9, 2025 19:17
- Add users table migration for Bluesky-authenticated users
- Implement user service with getOrCreateUser and getUserByHandle
- Complete verify-challenge endpoint to create users and sessions
- Add session management helpers (getSession, clearSession)
- Add logout endpoint
- Enhance accounts used display on match and compare pages
- Improve methodology page with account selection transparency
- Add health check endpoint (/api/health)
- Improve error messages throughout with actionable guidance
- Add loading states and spinners for async operations
- Add better error styling and user feedback
Co-authored-by: anitabansal.flights <anitabansal.flights@gmail.com>
Co-authored-by: anitabansal.flights <anitabansal.flights@gmail.com>
Co-authored-by: anitabansal.flights <anitabansal.flights@gmail.com>
@coderabbitai

coderabbitai Bot commented Dec 10, 2025

Copy link
Copy Markdown

Walkthrough

This PR introduces a complete session management and user authentication system. It adds session utilities for cookie-based authentication, a user service that integrates with Bluesky and Supabase to manage user records, updates the authentication flow to create/update users after verification, implements session cookies and logout functionality, adds a health check endpoint, and enhances UI across multiple pages for improved account display and error handling.

Changes

Cohort / File(s) Summary
Core Session & User Management
src/lib/auth/session.ts, src/lib/services/userService.ts
New session module exports SessionData type and functions for parsing, clearing, and retrieving session cookies. New user service exports User type and functions to resolve Bluesky DIDs, upsert users to Supabase, and retrieve user data by handle.
Authentication Routes
src/routes/api/auth/bsky/create-challenge/+server.ts
Enhanced validation for Bluesky handles with early checks for missing handles and invalid format, returning 400 with descriptive error messages and codes.
Authentication Routes
src/routes/api/auth/bsky/verify-challenge/+server.ts
Major refactor replacing direct Supabase handling with getOrCreateUser call; now receives cookies parameter, creates/updates user after verification, sets session cookie with userId/handle/verifiedAt, and returns expanded response with user object instead of just handle.
Authentication Routes
src/routes/api/auth/logout/+server.ts
New POST endpoint that clears the session cookie via clearSession utility and returns success confirmation or error response.
Infrastructure
src/routes/api/health/+server.ts
New GET endpoint performing health checks for database (via Supabase) and Bluesky connectivity, returning structured status with overall health state and per-service details; responds with 503 if down, 200 otherwise.
Documentation
bugbot.md
New file codifying Bugbot rules for analysis, including authentication flow guidelines, database migration exclusions, and JavaScript style enforcement for src/\\.js files.
Frontend Pages
src/routes/compare/[matchId]/+page.svelte
Added descriptive paragraph explaining account contribution to sentiment analysis and title attributes on account chips displaying DIDs.
Frontend Pages
src/routes/match/[id]/+page.svelte
Enhanced error handling with detailed messages for snapshot and summary loading failures, introduced summaryMeta state, added loading spinner animation, improved visual separation with borders and padding, and expanded account display with DID tooltips and Learn More links.
Frontend Pages
src/routes/methodology/+page.svelte
Updated Eligibility Rules with explicit platform-aware criteria (500+ followers, 6 months for Bluesky, 36 months for Twitter/Threads), added admin guidance section, introduced Account Selection Transparency subsection detailing visibility across Pre-match/Live/Post-match windows.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant VerifyChallenge as verify-challenge<br/>Endpoint
    participant Bluesky
    participant UserService
    participant Supabase
    
    Client->>VerifyChallenge: POST verify-challenge<br/>(proof, cookies)
    VerifyChallenge->>Bluesky: Verify proof
    Bluesky-->>VerifyChallenge: ✓ Verified / Handle
    
    VerifyChallenge->>UserService: getOrCreateUser(handle)
    UserService->>Bluesky: resolveDidFromHandle(handle)
    Bluesky-->>UserService: DID
    UserService->>Bluesky: Fetch profile<br/>(displayName, avatar)
    Bluesky-->>UserService: Profile data
    
    UserService->>Supabase: Upsert user<br/>(bsky_handle, bsky_did, etc.)
    Supabase-->>UserService: User record
    UserService-->>VerifyChallenge: User object
    
    VerifyChallenge->>VerifyChallenge: Set session cookie<br/>(userId, handle, verifiedAt)
    VerifyChallenge->>Client: Return 200<br/>{ ok: true, user }
    Client->>Client: Store session cookie
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Areas requiring attention:

  • src/lib/services/userService.ts — New service with Bluesky API integration, DID resolution, and Supabase upsert logic; verify error handling paths and null fallbacks are correct
  • src/routes/api/auth/bsky/verify-challenge/+server.ts — Significant flow changes from direct Supabase to userService integration; verify session cookie options (httpOnly, secure, sameSite, maxAge) align with security requirements
  • src/routes/api/health/+server.ts — Dynamic import of @atproto/api and service connectivity checks; verify performance impact of health checks and appropriate timeouts
  • src/routes/match/[id]/+page.svelte — Enhanced error handling and new summaryMeta state management; verify error message parsing and UI state transitions are robust

Poem

🐰 A session springs forth, a cookie so sweet,
Where Bluesky and Supabase gracefully meet,
With DIDs resolved and users secure,
Our burrow's auth flow is perfectly pure!
Logout, health checks, and accounts on display—
Hopping through systems in a brand new way! 🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Coderabbit review' is vague and generic, failing to describe any actual change in the pull request. The changeset includes authentication flow, session management, user service, health checks, UI improvements, and documentation—none of which are conveyed by this title. Replace with a descriptive title summarizing the main change, such as 'Add Bluesky authentication and session management' or 'Implement user authentication with Bluesky integration and session handling'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/user-auth-ui-improvements-review-2

Comment @coderabbitai help to get the list of available commands and usage tips.

@smb060606

Copy link
Copy Markdown
Collaborator Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Dec 10, 2025

Copy link
Copy Markdown
✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
src/routes/match/[id]/+page.svelte (1)

118-118: Consider extracting the inline type definition.

The inline type annotation is detailed and makes the line quite long. For improved maintainability, consider extracting this to a type alias at the top of the script block.

Apply this diff to extract the type:

+type SummaryMeta = {
+  phase?: string;
+  accountsUsed?: Array<{ did: string; handle: string; displayName?: string }>;
+  liveBin?: { index: number; startMinute: number; endMinute: number };
+} | null;
+
-let summaryMeta: { phase?: string; accountsUsed?: Array<{ did: string; handle: string; displayName?: string }>; liveBin?: { index: number; startMinute: number; endMinute: number } } | null = null;
+let summaryMeta: SummaryMeta = null;
src/routes/compare/[matchId]/+page.svelte (1)

111-113: DID tooltip and chip label formatting are sound; consider optional a11y tweak

The tooltip binding and handle/display name composition are correct and will behave as expected. Optionally, if some entries can lack DIDs, you might provide a human‑readable fallback (or an aria-label) instead of an empty title to improve accessibility.

src/lib/auth/session.ts (1)

2-2: Remove unused import.

The getUserByHandle import is not used in this file.

Apply this diff:

-import { getUserByHandle } from '$lib/services/userService';
src/lib/services/userService.ts (2)

38-45: Consider removing unnecessary optional chaining.

The optional chaining on getProfile is unnecessary since BskyAgent should always have this method. While not causing a bug here (unlike in the health check), removing it improves code clarity.

Apply this diff:

 async function resolveDidFromHandle(handle: string): Promise<string | null> {
   try {
     const agent = await getAgent();
-    const res: any = await (agent as any).getProfile?.({ actor: handle });
+    const res: any = await (agent as any).getProfile({ actor: handle });
     return res?.data?.did ?? null;
   } catch {
     return null;
   }
 }

99-109: Consider extracting User object mapping.

The code for mapping database fields to the User type is duplicated between getOrCreateUser and getUserByHandle. Extract this to a helper function to reduce duplication.

Add a helper function:

function mapDbRowToUser(data: any): User {
  return {
    id: data.id,
    bskyHandle: data.bsky_handle,
    bskyDid: data.bsky_did,
    displayName: data.display_name,
    avatarUrl: data.avatar_url,
    verifiedAt: data.verified_at,
    lastSeenAt: data.last_seen_at,
    createdAt: data.created_at,
    updatedAt: data.updated_at
  };
}

Then use it in both functions:

   if (error) {
     console.error('getOrCreateUser: upsert failed', { error: String(error) });
     return null;
   }

-  return {
-    id: data.id,
-    bskyHandle: data.bsky_handle,
-    bskyDid: data.bsky_did,
-    displayName: data.display_name,
-    avatarUrl: data.avatar_url,
-    verifiedAt: data.verified_at,
-    lastSeenAt: data.last_seen_at,
-    createdAt: data.created_at,
-    updatedAt: data.updated_at
-  };
+  return mapDbRowToUser(data);

Also applies to: 128-138

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Jira integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between fe0f7d2 and 9f26122.

⛔ Files ignored due to path filters (1)
  • supabase/migrations/005_create_users.sql is excluded by !**/*.sql
📒 Files selected for processing (10)
  • bugbot.md (1 hunks)
  • src/lib/auth/session.ts (1 hunks)
  • src/lib/services/userService.ts (1 hunks)
  • src/routes/api/auth/bsky/create-challenge/+server.ts (2 hunks)
  • src/routes/api/auth/bsky/verify-challenge/+server.ts (1 hunks)
  • src/routes/api/auth/logout/+server.ts (1 hunks)
  • src/routes/api/health/+server.ts (1 hunks)
  • src/routes/compare/[matchId]/+page.svelte (1 hunks)
  • src/routes/match/[id]/+page.svelte (9 hunks)
  • src/routes/methodology/+page.svelte (2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.*

⚙️ CodeRabbit configuration file

Do not provide comments on .sql migration files that are not included code diff in the PR being reviewed

Files:

  • src/routes/api/health/+server.ts
  • bugbot.md
  • src/routes/api/auth/logout/+server.ts
  • src/routes/methodology/+page.svelte
  • src/routes/api/auth/bsky/create-challenge/+server.ts
  • src/lib/services/userService.ts
  • src/routes/api/auth/bsky/verify-challenge/+server.ts
  • src/routes/compare/[matchId]/+page.svelte
  • src/lib/auth/session.ts
  • src/routes/match/[id]/+page.svelte
🧬 Code graph analysis (4)
src/routes/api/health/+server.ts (3)
src/lib/supabaseAdmin.ts (1)
  • getSupabaseAdmin (10-33)
src/lib/supabaseClient.ts (1)
  • getSupabaseClient (5-22)
src/lib/config/bsky.ts (1)
  • BSKY_APPVIEW_BASE (1-1)
src/routes/api/auth/logout/+server.ts (1)
src/lib/auth/session.ts (1)
  • clearSession (30-32)
src/lib/services/userService.ts (2)
src/lib/config/bsky.ts (1)
  • BSKY_APPVIEW_BASE (1-1)
src/lib/supabaseAdmin.ts (1)
  • getSupabaseAdmin (10-33)
src/routes/api/auth/bsky/verify-challenge/+server.ts (3)
src/routes/api/auth/bsky/create-challenge/+server.ts (1)
  • POST (4-63)
src/lib/auth/bskyVerifyStore.ts (3)
  • getChallenge (46-55)
  • verifyPostContainsCode (66-93)
  • clearChallenge (57-60)
src/lib/services/userService.ts (1)
  • getOrCreateUser (53-110)
🪛 LanguageTool
bugbot.md

[style] ~11-~11: This wording can make your sentence hard to follow. Try rephrasing for improved clarity.
Context: ...r creation. If user creation fails (e.g., due to database errors), users will need to re...

(DUE_TO_BECAUSE)

🔇 Additional comments (22)
src/routes/match/[id]/+page.svelte (7)

94-107: Excellent error handling enhancements.

The improved error parsing flow (JSON → text fallback) and logging provide better debugging and user feedback. The implementation correctly handles both structured and unstructured error responses.


147-173: Well-implemented comprehensive error handling.

The error handling properly addresses multiple failure scenarios (rate limiting, timeouts, missing API keys) with user-friendly messages. The retry time calculation for rate limits is particularly helpful.


189-196: LGTM: Smooth UI transitions and loading animation.

The CSS enhancements (smooth tab transitions, proper hover/disabled states, and spin keyframes) improve the visual polish and user experience.


225-239: Great UX improvements for account display.

The additions—visual separators, descriptive captions, methodology link, and DID tooltips—significantly enhance user understanding and accessibility of the live account monitoring feature.


252-254: Clear error state presentation.

The error styling provides appropriate visual emphasis with good contrast and padding, making errors immediately recognizable to users.


294-307: Consistent and polished account display.

The enhancements mirror the live section pattern, maintaining visual and informational consistency. The dynamic phase label ({active}) appropriately contextualizes the account usage.


350-358: Enhanced loading and error states.

The addition of a visual spinner during summary generation improves perceived responsiveness, and the styled error display maintains consistency with other error presentations in the component.

src/routes/compare/[matchId]/+page.svelte (1)

105-108: Clear context and methodology link for “Accounts Used”

The added explanatory copy and link nicely clarify what this section represents and how accounts are selected; markup and interpolation look correct and side‑effect free.

src/lib/auth/session.ts (1)

30-32: LGTM!

The session clearing logic is straightforward and correct.

src/routes/api/auth/logout/+server.ts (1)

8-33: LGTM!

The logout endpoint correctly clears the session and returns appropriate responses. The error handling is defensive and appropriate.

src/routes/api/auth/bsky/create-challenge/+server.ts (3)

9-20: LGTM!

Clear validation with helpful error message for missing handles.


22-34: LGTM!

Basic format validation helps catch obvious mistakes before expensive API calls. The actual handle validity is confirmed when verifying the challenge via Bluesky API.


51-61: LGTM!

Error handling provides clear messages for users while maintaining appropriate status codes.

src/routes/api/health/+server.ts (2)

74-81: LGTM!

The overall status determination logic and HTTP status code mapping are appropriate for a health check endpoint.


83-89: LGTM!

Response headers are well-configured with appropriate cache control for a health check endpoint.

src/routes/api/auth/bsky/verify-challenge/+server.ts (4)

53-54: LGTM!

Clearing the challenge before user creation is an intentional design decision documented in bugbot.md. The trade-off is acceptable for this application.

Based on learnings, this pattern should not be flagged as requiring the challenge to be cleared only after successful user creation.


56-69: LGTM!

User creation error handling is appropriate, with clear error messages returned to the client.


71-84: LGTM!

Session cookie configuration is appropriate. Note that the lack of cryptographic signing was already flagged in the review of src/lib/auth/session.ts, and the inline comment acknowledges this as a simplified approach.


86-101: LGTM!

Response payload is well-structured with appropriate headers to prevent caching of authentication responses.

src/lib/services/userService.ts (3)

17-33: LGTM!

The lazy singleton pattern for the Bluesky agent is efficient and appropriate for public API access.


53-110: LGTM!

The upsert logic correctly handles user creation and updates. The last_seen_at field is intentionally updated on every call as documented in the function comment, which is appropriate for tracking user activity.


115-139: LGTM!

The user lookup logic is straightforward and handles errors appropriately.

Comment thread src/lib/auth/session.ts
Comment on lines +14 to +25
export function getSession(cookies: Cookies): SessionData | null {
try {
const sessionCookie = cookies.get('session');
if (!sessionCookie) return null;
const session = JSON.parse(sessionCookie) as SessionData;
// Basic validation
if (!session.userId || !session.handle || !session.verifiedAt) return null;
return session;
} catch {
return null;
}
}

@coderabbitai coderabbitai Bot Dec 10, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add session integrity verification.

Session cookies lack cryptographic signature verification, allowing attackers to forge cookies with arbitrary userId and handle values. This enables authentication bypass.

Consider these solutions:

  1. Use signed cookies with SvelteKit's built-in signing:
 export function getSession(cookies: Cookies): SessionData | null {
   try {
-    const sessionCookie = cookies.get('session');
+    const sessionCookie = cookies.get('session', { signed: true });
     if (!sessionCookie) return null;
     const session = JSON.parse(sessionCookie) as SessionData;
  1. Use JWT for tamper-proof sessions with expiration and signature validation.

  2. Leverage Supabase Auth for production-grade session management (as noted in verify-challenge comments).

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/lib/auth/session.ts around lines 14 to 25, the session cookie is parsed
blindly allowing forged values; update this function to verify cookie integrity
before trusting its contents: either use SvelteKit signed cookies (verify with
the server-side signing key) or switch to signed JWTs — read the raw cookie,
validate its signature and expiration using the server secret (from env), only
then parse and cast the payload to SessionData, and return null on any
verification failure or missing claims (userId, handle, verifiedAt); ensure all
verification errors are handled explicitly and no unsigned/plain JSON is
accepted.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CodeRabbit - what is the impact to the user if i do not implement this suggestion?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smb060606 Without session integrity verification, an attacker can completely bypass authentication and impersonate any user. Here's the practical impact:

Attack Scenario

  1. An attacker opens browser DevTools
  2. Creates a fake cookie: session={"userId":"victim-id-123","handle":"victim.bsky.social","verifiedAt":"2025-12-10T00:00:00Z"}
  3. Your application accepts this forged session as legitimate
  4. Attacker gains full access to the victim's account

Real Impact on Users

  • Account Takeover: Attackers can access any user's account without knowing their credentials
  • Data Breach: Read private data, messages, or profile information
  • Unauthorized Actions: Post content, modify settings, or perform actions as the victim
  • No Audit Trail: These forged sessions bypass your authentication flow, making attacks hard to detect

Severity

This is a critical vulnerability for any production application handling real user data. The attack requires:

  • ✅ No special tools (just browser DevTools)
  • ✅ No credentials needed
  • ✅ Trivial to execute (30 seconds)

Bottom Line

If this code goes to production with real users, every account is vulnerable to trivial takeover. For a proof-of-concept or development environment, the risk is lower, but should still be addressed before any real user data is involved.

Comment on lines +44 to +48
if (!client) {
health.services.database = 'down';
health.status = 'degraded';
hasErrors = true;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Inconsistent status when database is unavailable.

When no Supabase client is available, the database is marked as 'down' but the overall status is set to 'degraded'. This is inconsistent with the logic at lines 75-76, which sets overall status to 'down' when database is down.

Apply this diff:

       if (!client) {
         health.services.database = 'down';
-        health.status = 'degraded';
+        health.status = 'down';
         hasErrors = true;
       }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!client) {
health.services.database = 'down';
health.status = 'degraded';
hasErrors = true;
}
if (!client) {
health.services.database = 'down';
health.status = 'down';
hasErrors = true;
}
🤖 Prompt for AI Agents
In src/routes/api/health/+server.ts around lines 44 to 48, the code marks the
database service as 'down' but sets the overall health.status to 'degraded',
which is inconsistent with later logic that sets status to 'down' when the
database is down; change the assignment so that when client is missing
health.services.database = 'down' and health.status = 'down' (leave hasErrors =
true), ensuring the overall status reflects the database outage consistently.

Comment on lines +56 to +72
// Check Bluesky connectivity (lightweight check)
try {
const { BskyAgent } = await import('@atproto/api');
const { BSKY_APPVIEW_BASE } = await import('$lib/config/bsky');
const base = BSKY_APPVIEW_BASE.endsWith('/xrpc')
? BSKY_APPVIEW_BASE.slice(0, -('/xrpc'.length))
: BSKY_APPVIEW_BASE;
const agent = new BskyAgent({ service: base });
// Try a lightweight operation (this will fail fast if unreachable)
await (agent as any).getProfile?.({ actor: 'bsky.app' }).catch(() => {
throw new Error('Bluesky unreachable');
});
health.services.bluesky = 'ok';
} catch {
health.services.bluesky = 'degraded';
// Don't mark overall as down for Bluesky issues
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix optional chaining in Bluesky health check.

Line 65 uses optional chaining on a method that should always exist, then chains .catch() on the result. If getProfile is undefined, getProfile?.(...) returns undefined, and calling .catch() on undefined will throw a TypeError.

Apply this diff to remove unnecessary optional chaining:

     const agent = new BskyAgent({ service: base });
     // Try a lightweight operation (this will fail fast if unreachable)
-    await (agent as any).getProfile?.({ actor: 'bsky.app' }).catch(() => {
+    await (agent as any).getProfile({ actor: 'bsky.app' }).catch(() => {
       throw new Error('Bluesky unreachable');
     });

Alternatively, check for the method's existence before calling:

     const agent = new BskyAgent({ service: base });
-    await (agent as any).getProfile?.({ actor: 'bsky.app' }).catch(() => {
-      throw new Error('Bluesky unreachable');
-    });
+    if (typeof (agent as any).getProfile === 'function') {
+      await (agent as any).getProfile({ actor: 'bsky.app' }).catch(() => {
+        throw new Error('Bluesky unreachable');
+      });
+    } else {
+      throw new Error('Bluesky API not available');
+    }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Check Bluesky connectivity (lightweight check)
try {
const { BskyAgent } = await import('@atproto/api');
const { BSKY_APPVIEW_BASE } = await import('$lib/config/bsky');
const base = BSKY_APPVIEW_BASE.endsWith('/xrpc')
? BSKY_APPVIEW_BASE.slice(0, -('/xrpc'.length))
: BSKY_APPVIEW_BASE;
const agent = new BskyAgent({ service: base });
// Try a lightweight operation (this will fail fast if unreachable)
await (agent as any).getProfile?.({ actor: 'bsky.app' }).catch(() => {
throw new Error('Bluesky unreachable');
});
health.services.bluesky = 'ok';
} catch {
health.services.bluesky = 'degraded';
// Don't mark overall as down for Bluesky issues
}
// Check Bluesky connectivity (lightweight check)
try {
const { BskyAgent } = await import('@atproto/api');
const { BSKY_APPVIEW_BASE } = await import('$lib/config/bsky');
const base = BSKY_APPVIEW_BASE.endsWith('/xrpc')
? BSKY_APPVIEW_BASE.slice(0, -('/xrpc'.length))
: BSKY_APPVIEW_BASE;
const agent = new BskyAgent({ service: base });
// Try a lightweight operation (this will fail fast if unreachable)
await (agent as any).getProfile({ actor: 'bsky.app' }).catch(() => {
throw new Error('Bluesky unreachable');
});
health.services.bluesky = 'ok';
} catch {
health.services.bluesky = 'degraded';
// Don't mark overall as down for Bluesky issues
}
🤖 Prompt for AI Agents
In src/routes/api/health/+server.ts around lines 56 to 72, the Bluesky health
check uses optional chaining on getProfile and then calls .catch on its result
which can be undefined; remove the unnecessary optional chaining and call
getProfile directly (await agent.getProfile({ actor: 'bsky.app' })) so errors
are caught by the outer try/catch, or explicitly guard the method first (if
(typeof agent.getProfile !== 'function') throw new Error('Bluesky client missing
getProfile'); await agent.getProfile({ actor: 'bsky.app' })); this prevents a
TypeError from calling .catch on undefined and ensures connectivity errors are
handled by the existing catch block.

@smb060606 smb060606 closed this Dec 10, 2025
@smb060606

Copy link
Copy Markdown
Collaborator Author

N/A

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants