const settingsSocketRef = ref(socketManagerRef.value?.settingsSocket)
const loadSettings = async (): Promise<Result<void, NetworkError>> => {
isLoading.value = true
error.value = undefined
const connectionResult = await ensureConnected()
if (connectionResult.isErr()) {
error.value = connectionResult.error.message
isLoading.value = false
return err(connectionResult.error)
}
const emitResult = await emitWithTimeout<UserSettingWire[]>(
settingsSocketRef, // Here is the error
'settings:getAll',
undefined,
{
signal: abortController.signal,
timeoutMs: socketTimeoutMs.settings,
}
)
if (emitResult.isErr()) {
error.value = emitResult.error.message
isLoading.value = false
return err(emitResult.error)
}
settings.value = emitResult.value.map(fromWire)
isLoading.value = false
return ok(undefined)
}
#What's going wrong here?
19 messages · Page 1 of 1 (latest)
Argument of type 'Ref<{ readonly isConnected: boolean; init: () => Promise<Result<void, SocketError>>; updateAuthToken: (token: string) => void; waitForConnection: (timeoutMilliseconds?: number) => Promise<...>; ... 9 more ...; readonly subscriptionSocket: ...; } | undefined, SocketManager | ... 1 more ... | undefined>' is not assignable to parameter of type 'Ref<Socket<DefaultEventsMap, DefaultEventsMap> | null | undefined, Socket<DefaultEventsMap, DefaultEventsMap> | null | undefined>'.
Type '{ readonly isConnected: boolean; init: () => Promise<Result<void, SocketError>>; updateAuthToken: (token: string) => void; waitForConnection: (timeoutMilliseconds?: number) => Promise<...>; ... 9 more ...; readonly subscriptionSocket: ...; } | undefined' is not assignable to type 'Socket<DefaultEventsMap, DefaultEventsMap> | null | undefined'.
Type '{ readonly isConnected: boolean; init: () => Promise<Result<void, SocketError>>; updateAuthToken: (token: string) => void; waitForConnection: (timeoutMilliseconds?: number) => Promise<...>; ... 9 more ...; readonly subscriptionSocket: ...; }' is missing the following properties from type 'Socket<DefaultEventsMap, DefaultEventsMap>': io, id, _pid, _lastOffset, and 58 more.
Shared
export type UserSettingWithValidation = {
readonly settingKey: string
readonly settingValue: unknown
readonly dataType: 'string' | 'number' | 'boolean'
readonly updatedAt: Date
readonly category: string
readonly encrypted: boolean
readonly required: boolean
readonly description: string
readonly minLength?: number
readonly maxLength?: number
readonly minValue?: number
readonly maxValue?: number
}
/**
* Wire-safe type for socket transmission (Date → ISO string)
*/
export type UserSettingWire = Omit<UserSettingWithValidation, 'updatedAt'> & {
readonly updatedAt: string
}
emit-with-timeout.ts
import type { Ref } from 'vue'
import { ResultAsync } from 'neverthrow'
import { NetworkError, SocketError } from '@/errors'
import { socketTimeoutMs } from '@/constants'
import type { Socket } from 'socket.io-client'
type SocketResponse<T> = {
success: boolean
data?: T
error?: string
}
const defaultTimeout = socketTimeoutMs.default
export function emitWithTimeout<T = void>(
socketRef: Ref<Socket | null | undefined>,
event: string,
payload?: unknown,
options?: { timeoutMs?: number; signal?: AbortSignal }
): ResultAsync<T, NetworkError> {
const socket = socketRef.value
if (!socket) {
return ResultAsync.fromSafePromise(Promise.reject(new SocketError('Socket not connected')))
}
// We assume the socket is already ready
return ResultAsync.fromPromise(
new Promise<T>((resolve, reject) => {
const timeoutMs = options?.timeoutMs ?? defaultTimeout
const signal = options?.signal
if (signal?.aborted) {
reject(new NetworkError('Request aborted'))
return
}
const abortHandler = () => {
reject(new NetworkError('Request aborted'))
}
signal?.addEventListener('abort', abortHandler, { once: true })
socket
.timeout(timeoutMs)
.emit(event, payload, (err: unknown, response: SocketResponse<T>) => {
signal?.removeEventListener('abort', abortHandler)
if (err) {
const message = err instanceof Error ? err.message : String(err)
reject(new NetworkError(message))
} else if (!response.success) {
reject(new NetworkError(response.error ?? `Failed to ${event}`))
} else {
resolve(response.data as T)
}
})
}),
(error) => (error instanceof NetworkError ? error : new NetworkError(String(error)))
)
}
it really helps to have a playground someone can use to see the real error
no idea if this is reproduced correctly, or if its fixed correctly, but for future helpers:
Preview:```ts
import type {Ref} from "vue"
import {ResultAsync} from "neverthrow"
import type {Socket} from "socket.io-client"
const socketTimeoutMs = {default: 500, settings: 900}
class NetworkError extends Error {}
class SocketError extends Error {}
export type UserSettingWithValidation = {
...```
You can choose specific lines to embed by selecting them before copying the link.
does that fix your issue for real?
eh what do you mean
I posted a playground, you may not be able to see it if you have Show embeds and preview website links pasted into chat turned off?
ah, down below I have emitResult1 that doesn't have the error
AH thanks, I am about to take a look