Browse Source

fixed toast and auth response

imwald
Silberengel 5 months ago
parent
commit
cd9ae1094d
  1. 10
      src/components/RelayStatusDisplay/index.tsx
  2. 91
      src/services/client.service.ts

10
src/components/RelayStatusDisplay/index.tsx

@ -1,4 +1,4 @@
import { Check, X, AlertCircle } from 'lucide-react' import { Check, X } from 'lucide-react'
import { simplifyUrl } from '@/lib/url' import { simplifyUrl } from '@/lib/url'
interface RelayStatus { interface RelayStatus {
@ -50,10 +50,10 @@ export default function RelayStatusDisplay({
<span className="font-mono text-xs truncate"> <span className="font-mono text-xs truncate">
{simplifyUrl(status.url)} {simplifyUrl(status.url)}
</span> </span>
{status.authAttempted && ( {status.authAttempted && !status.success && (
<div title="Authentication attempted"> <span className="text-xs text-red-600 dark:text-red-400">
<AlertCircle className="h-3 w-3 text-amber-500" /> (auth failed)
</div> </span>
)} )}
</div> </div>

91
src/services/client.service.ts

@ -142,9 +142,12 @@ class ClientService extends EventTarget {
// Use current user's relay list // Use current user's relay list
const relayList = this.pubkey ? await this.fetchRelayList(this.pubkey) : { write: [], read: [] } const relayList = this.pubkey ? await this.fetchRelayList(this.pubkey) : { write: [], read: [] }
console.log('DEBUG: User relay list write URLs:', relayList?.write)
const senderWriteRelays = relayList?.write.slice(0, 6) ?? [] const senderWriteRelays = relayList?.write.slice(0, 6) ?? []
console.log('DEBUG: Selected sender write relays:', senderWriteRelays)
const recipientReadRelays = Array.from(new Set(_additionalRelayUrls)) const recipientReadRelays = Array.from(new Set(_additionalRelayUrls))
relays = senderWriteRelays.concat(recipientReadRelays) relays = senderWriteRelays.concat(recipientReadRelays)
console.log('DEBUG: Final relay URLs before optimization:', relays)
} }
if (!relays.length) { if (!relays.length) {
@ -238,6 +241,7 @@ class ClientService extends EventTarget {
totalCount: number totalCount: number
}> { }> {
const uniqueRelayUrls = this.optimizeRelaySelection(Array.from(new Set(relayUrls))) const uniqueRelayUrls = this.optimizeRelaySelection(Array.from(new Set(relayUrls)))
console.log('DEBUG: uniqueRelayUrls after optimization:', uniqueRelayUrls)
const relayStatuses: Array<{ const relayStatuses: Array<{
url: string url: string
@ -260,13 +264,17 @@ class ClientService extends EventTarget {
const checkCompletion = () => { const checkCompletion = () => {
if (resolved) return if (resolved) return
// If one third of the relays have accepted the event, consider it a success // Wait for all relays to complete before resolving (don't complete early)
const isSuccess = successCount >= Math.max(1, Math.ceil(uniqueRelayUrls.length / 3)) // This ensures we show the full relay status information
if (isSuccess && !resolved) { if (finishedCount >= uniqueRelayUrls.length && !resolved) {
this.emitNewEvent(event) const isSuccess = successCount > 0
if (isSuccess) {
this.emitNewEvent(event)
}
resolved = true resolved = true
console.log('DEBUG: Publishing completed. relayStatuses:', relayStatuses)
resolve({ resolve({
success: true, success: isSuccess,
relayStatuses, relayStatuses,
successCount, successCount,
totalCount: uniqueRelayUrls.length totalCount: uniqueRelayUrls.length
@ -274,35 +282,26 @@ class ClientService extends EventTarget {
return return
} }
if (finishedCount >= uniqueRelayUrls.length && !resolved) { // Handle case where no relays succeed
if (successCount > 0) { if (finishedCount >= uniqueRelayUrls.length && !resolved && successCount === 0) {
this.emitNewEvent(event) resolved = true
resolved = true console.log('DEBUG: All relays failed. relayStatuses:', relayStatuses)
resolve({ const aggregateError = new AggregateError(
success: true, errors.map(
relayStatuses, ({ url, error }) => {
successCount, let errorMsg = 'Unknown error'
totalCount: uniqueRelayUrls.length if (error instanceof Error) {
}) errorMsg = error.message || 'Empty error message'
} else { } else if (error !== null && error !== undefined) {
resolved = true errorMsg = String(error)
const aggregateError = new AggregateError(
errors.map(
({ url, error }) => {
let errorMsg = 'Unknown error'
if (error instanceof Error) {
errorMsg = error.message || 'Empty error message'
} else if (error !== null && error !== undefined) {
errorMsg = String(error)
}
return new Error(`Failed to publish to ${url}: ${errorMsg}`)
} }
) return new Error(`Failed to publish to ${url}: ${errorMsg}`)
}
) )
// Attach relay statuses to the error so they can be displayed )
;(aggregateError as any).relayStatuses = relayStatuses // Attach relay statuses to the error so they can be displayed
reject(aggregateError) ;(aggregateError as any).relayStatuses = relayStatuses
} reject(aggregateError)
} }
} }
@ -329,6 +328,7 @@ class ClientService extends EventTarget {
// eslint-disable-next-line @typescript-eslint/no-this-alias // eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this const that = this
console.log('DEBUG: Attempting to publish to relay:', url)
try { try {
// Throttle requests to prevent "too many concurrent REQs" errors // Throttle requests to prevent "too many concurrent REQs" errors
await this.throttleRequest(url) await this.throttleRequest(url)
@ -336,7 +336,9 @@ class ClientService extends EventTarget {
const relay = await this.pool.ensureRelay(url) const relay = await this.pool.ensureRelay(url)
relay.publishTimeout = 8_000 // 8s relay.publishTimeout = 8_000 // 8s
console.log('DEBUG: Publishing to relay:', url)
await relay.publish(event) await relay.publish(event)
console.log('DEBUG: Successfully published to relay:', url)
this.trackEventSeenOn(event.id, relay) this.trackEventSeenOn(event.id, relay)
this.recordSuccess(url) this.recordSuccess(url)
successCount++ successCount++
@ -349,6 +351,7 @@ class ClientService extends EventTarget {
checkCompletion() checkCompletion()
} catch (error) { } catch (error) {
console.log('DEBUG: Failed to publish to relay:', url, 'Error:', error)
let errorMessage = 'Unknown error' let errorMessage = 'Unknown error'
if (error instanceof Error) { if (error instanceof Error) {
errorMessage = error.message || 'Empty error message' errorMessage = error.message || 'Empty error message'
@ -384,17 +387,31 @@ class ClientService extends EventTarget {
error.message.startsWith('auth-required') && error.message.startsWith('auth-required') &&
!!that.signer !!that.signer
) { ) {
console.log('DEBUG: Attempting authentication for relay:', url)
try { try {
// Throttle auth requests too // Throttle auth requests too
await this.throttleRequest(url) await this.throttleRequest(url)
const relay = await this.pool.ensureRelay(url) const relay = await this.pool.ensureRelay(url)
await relay.auth((authEvt: EventTemplate) => {
// Attempt auth with proper timeout handling
console.log('DEBUG: Starting auth for relay:', url)
const authPromise = relay.auth((authEvt: EventTemplate) => {
// Ensure the auth event has the correct pubkey // Ensure the auth event has the correct pubkey
const authEventWithPubkey = { ...authEvt, pubkey: that.pubkey } const authEventWithPubkey = { ...authEvt, pubkey: that.pubkey }
return that.signer!.signEvent(authEventWithPubkey) return that.signer!.signEvent(authEventWithPubkey)
}) })
const authTimeoutPromise = new Promise((_, reject) => {
setTimeout(() => reject(new Error('Auth timeout')), 8000) // 8s timeout
})
await Promise.race([authPromise, authTimeoutPromise])
console.log('DEBUG: Auth successful for relay:', url)
await relay.publish(event) await relay.publish(event)
console.log('DEBUG: Publish successful for relay:', url)
this.trackEventSeenOn(event.id, relay) this.trackEventSeenOn(event.id, relay)
this.recordSuccess(url) this.recordSuccess(url)
successCount++ successCount++
@ -408,6 +425,7 @@ class ClientService extends EventTarget {
checkCompletion() checkCompletion()
} catch (authError) { } catch (authError) {
console.log('DEBUG: Auth failed for relay:', url, 'Error:', authError)
let authErrorMessage = 'Unknown auth error' let authErrorMessage = 'Unknown auth error'
if (authError instanceof Error) { if (authError instanceof Error) {
authErrorMessage = authError.message || 'Empty auth error message' authErrorMessage = authError.message || 'Empty auth error message'
@ -1479,7 +1497,7 @@ class ClientService extends EventTarget {
return getRelayListFromEvent(event) return getRelayListFromEvent(event)
} }
return { return {
write: BIG_RELAY_URLS, write: Array.from(new Set([...FAST_WRITE_RELAY_URLS, ...BIG_RELAY_URLS])).slice(0, 8), // Combine fast write + big relays for better redundancy (deduplicated)
read: BIG_RELAY_URLS, read: BIG_RELAY_URLS,
originalRelays: [] originalRelays: []
} }
@ -1730,11 +1748,6 @@ class ClientService extends EventTarget {
// Skip empty or invalid URLs // Skip empty or invalid URLs
if (!url || typeof url !== 'string') return false if (!url || typeof url !== 'string') return false
// Skip localhost URLs that might be misconfigured
if (url.includes('localhost:7777') || url.includes('localhost:5173')) {
return false
}
// Skip relays with open circuit breaker // Skip relays with open circuit breaker
if (this.isCircuitBreakerOpen(url)) { if (this.isCircuitBreakerOpen(url)) {
console.warn(`Skipping relay with open circuit breaker: ${url}`) console.warn(`Skipping relay with open circuit breaker: ${url}`)

Loading…
Cancel
Save