also looking at this
Actionable Bluesky publish errors + refresh-failure handling (#17)
#24
3 files
+89
-4
| @@ -1,6 +1,7 @@ | ||
| 1 | 1 | import type { BlueskySession, CrosspostTargetResult, PublishContent, PublishedPost, TimelineResult } from '../../Support/Social/types' |
| 2 | 2 | import { db } from '@stacksjs/database' |
| 3 | 3 | import { env } from '@stacksjs/env' |
| 4 | import { describeBlueskyError } from '../../Support/Social/bluesky-errors' | |
| 4 | 5 | import { BlueskyApiError, BlueskyDriver } from './Drivers/BlueskyDriver' |
| 5 | 6 | |
| 6 | 7 | const database = db as any |
| @@ -261,7 +262,7 @@ export class BlueskyService { | ||
| 261 | 262 | } |
| 262 | 263 | } |
| 263 | 264 | catch (error) { |
| 264 | const message = error instanceof Error ? error.message : String(error) | |
| 265 | const message = describeBlueskyError(error) | |
| 265 | 266 | const failedAt = now() |
| 266 | 267 | await database.updateTable('post_targets').set({ |
| 267 | 268 | status: 'failed', |
| @@ -388,9 +389,21 @@ export class BlueskyService { | ||
| 388 | 389 | throw error |
| 389 | 390 | } |
| 390 | 391 | |
| 391 | const session = await this.driver.refreshSession(identity.refresh_token) | |
| 392 | const driver = await this.ensureDriver() | |
| 393 | const refreshed = await this.saveSession(session, driver) | |
| 392 | // Access JWT expired — refresh once and retry. If the refresh token is | |
| 393 | // also dead, mark the identity expired so /accounts prompts a reconnect. | |
| 394 | let refreshed: SocialIdentityRow | |
| 395 | try { | |
| 396 | const session = await this.driver.refreshSession(identity.refresh_token) | |
| 397 | const driver = await this.ensureDriver() | |
| 398 | refreshed = await this.saveSession(session, driver) | |
| 399 | } | |
| 400 | catch { | |
| 401 | await database.updateTable('social_identities') | |
| 402 | .set({ auth_status: 'expired', updated_at: now() }) | |
| 403 | .where('id', '=', identity.id) | |
| 404 | .execute() | |
| 405 | throw new Error('Bluesky session expired — reconnect your account on the Accounts page.') | |
| 406 | } | |
| 394 | 407 | return await callback(refreshed) |
| 395 | 408 | } |
| 396 | 409 | } |