import type { HeadscaleConnectionError } from './error'; /** * Represents an error returned by the Headscale API. */ export interface HeadscaleAPIError { requestUrl: `${string} ${string}`; statusCode: number; rawData: string; data: Record | null; } /** * Type guard to check if an error is a HeadscaleAPIError. * @param error - The error to check. * @returns True if the error is a HeadscaleAPIError, false otherwise. */ export function isApiError(error: unknown): error is HeadscaleAPIError { return ( error != null && typeof error === 'object' && 'requestUrl' in error && 'statusCode' in error && 'rawData' in error && 'data' in error ); } /** * Type guard to check if an error is a HeadscaleConnectionError. * @param error - The error to check. * @returns True if the error is a HeadscaleConnectionError, false otherwise. */ export function isConnectionError( error: unknown, ): error is HeadscaleConnectionError { return ( error != null && typeof error === 'object' && 'requestUrl' in error && 'errorCode' in error && 'errorMessage' in error && 'extraData' in error ); } /** * Type guard to check if an error is a DataUnauthorizedError. * This checks if the error has a `data` property with a `statusCode` of 401. * * @param error - The error to check. * @returns True if the error is a DataUnauthorizedError, false otherwise. */ export function isDataUnauthorizedError(error: unknown): boolean { return ( error != null && typeof error === 'object' && 'data' in error && typeof error.data === 'object' && error.data != null && 'statusCode' in error.data && error.data.statusCode === 401 ); } /** * Type guard to check if an error is a DataWithResponseInit wrapping a * HeadscaleAPIError. This is used in loaders/actions to handle errors thrown by * `data()` before they reach the ErrorBoundary. * * @param error - The error to check. * @returns True if the error is a DataWithResponseInit containing a * HeadscaleAPIError, false otherwise. */ export function isDataWithApiError( error: unknown, ): error is { data: HeadscaleAPIError } { return ( error != null && typeof error === 'object' && 'data' in error && isApiError(error.data) ); }