diff --git a/ably.d.ts b/ably.d.ts index fb3bf2dac0..3e30600a0a 100644 --- a/ably.d.ts +++ b/ably.d.ts @@ -719,38 +719,6 @@ declare namespace Types { mode: string; } - /** - * A generic Ably error object that contains an Ably-specific status code, and a generic status code. Errors returned from the Ably server are compatible with the `ErrorInfo` structure and should result in errors that inherit from `ErrorInfo`. - */ - class ErrorInfo extends Error { - /** - * Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json). - */ - code: number; - /** - * Additional message information, where available. - */ - message: string; - /** - * HTTP Status Code corresponding to this error, where applicable. - */ - statusCode: number; - /** - * The underlying cause of the error, where applicable. - */ - cause?: string | Error | ErrorInfo; - - /** - * Construct an ErrorInfo object. - * - * @param message - A string describing the error. - * @param code - Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json). - * @param statusCode - HTTP Status Code corresponding to this error. - * @param cause - The underlying cause of the error. - */ - constructor(message: string, code: number, statusCode: number, cause?: string | Error | ErrorInfo); - } - /** * Contains an Ably Token and its associated metadata. */ @@ -1592,7 +1560,7 @@ declare namespace Types { * @param params - The parameters to include in the URL query of the request. The parameters depend on the endpoint being queried. See the [REST API reference](https://ably.com/docs/api/rest-api) for the available parameters of each endpoint. * @param body - The JSON body of the request. * @param headers - Additional HTTP headers to include in the request. - * @returns A promise which, upon success, will be fulfilled with an {@link Types.HttpPaginatedResponse} response object returned by the HTTP request. This response object will contain an empty or JSON-encodable object. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with an {@link Types.HttpPaginatedResponse} response object returned by the HTTP request. This response object will contain an empty or JSON-encodable object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ request( method: string, @@ -1606,13 +1574,13 @@ declare namespace Types { * Queries the REST `/stats` API and retrieves your application's usage statistics. Returns a {@link Types.PaginatedResult} object, containing an array of {@link Types.Stats} objects. See the [Stats docs](https://ably.com/docs/general/statistics). * * @param params - A set of parameters which are used to specify which statistics should be retrieved. This parameter should be a {@link Types.StatsParams} object. For reasons of backwards compatibility this parameter will also accept `any`; this ability will be removed in the next major release of this SDK. If you do not provide this argument, then this method will use the default parameters described in the {@link Types.StatsParams} interface. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.PaginatedResult} object containing an array of {@link Types.Stats} objects. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.PaginatedResult} object containing an array of {@link Types.Stats} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ stats(params?: StatsParams | any): Promise>; /** * Retrieves the time from the Ably service as milliseconds since the Unix epoch. Clients that do not have access to a sufficiently well maintained time source and wish to issue Ably {@link Types.TokenRequest | `TokenRequest`s} with a more accurate timestamp should use the {@link Types.ClientOptions.queryTime} property instead of this method. * - * @returns A promise which, upon success, will be fulfilled with the time as milliseconds since the Unix epoch. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with the time as milliseconds since the Unix epoch. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ time(): Promise; @@ -1620,14 +1588,14 @@ declare namespace Types { * Publishes a {@link Types.BatchPublishSpec} object to one or more channels, up to a maximum of 100 channels. * * @param spec - A {@link Types.BatchPublishSpec} object. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch publish for each requested channel. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch publish for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPublish(spec: BatchPublishSpec): Promise>; /** * Publishes one or more {@link Types.BatchPublishSpec} objects to one or more channels, up to a maximum of 100 channels. * * @param specs - An array of {@link Types.BatchPublishSpec} objects. - * @returns A promise which, upon success, will be fulfilled with an array of {@link Types.BatchResult} objects containing information about the result of the batch publish for each requested channel for each provided {@link Types.BatchPublishSpec}. This array is in the same order as the provided {@link Types.BatchPublishSpec} array. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with an array of {@link Types.BatchResult} objects containing information about the result of the batch publish for each requested channel for each provided {@link Types.BatchPublishSpec}. This array is in the same order as the provided {@link Types.BatchPublishSpec} array. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPublish( specs: BatchPublishSpec[] @@ -1636,7 +1604,7 @@ declare namespace Types { * Retrieves the presence state for one or more channels, up to a maximum of 100 channels. Presence state includes the `clientId` of members and their current {@link Types.PresenceAction}. * * @param channels - An array of one or more channel names, up to a maximum of 100 channels. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch presence request for each requested channel. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch presence request for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPresence(channels: string[]): Promise[]>; /** @@ -1683,7 +1651,7 @@ declare namespace Types { * @param params - The parameters to include in the URL query of the request. The parameters depend on the endpoint being queried. See the [REST API reference](https://ably.com/docs/api/rest-api) for the available parameters of each endpoint. * @param body - The JSON body of the request. * @param headers - Additional HTTP headers to include in the request. - * @returns A promise which, upon success, will be fulfilled with the {@link Types.HttpPaginatedResponse} response object returned by the HTTP request. This response object will contain an empty or JSON-encodable object. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with the {@link Types.HttpPaginatedResponse} response object returned by the HTTP request. This response object will contain an empty or JSON-encodable object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ request( method: string, @@ -1697,27 +1665,27 @@ declare namespace Types { * Queries the REST `/stats` API and retrieves your application's usage statistics. Returns a {@link Types.PaginatedResult} object, containing an array of {@link Types.Stats} objects. See the [Stats docs](https://ably.com/docs/general/statistics). * * @param params - A set of parameters which are used to specify which statistics should be retrieved. This parameter should be a {@link Types.StatsParams} object. For reasons of backwards compatibility this parameter will also accept `any`; this ability will be removed in the next major release of this SDK. If you do not provide this argument, then this method will use the default parameters described in the {@link Types.StatsParams} interface. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.PaginatedResult} object containing an array of {@link Types.Stats} objects. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.PaginatedResult} object containing an array of {@link Types.Stats} objects. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ stats(params?: StatsParams | any): Promise>; /** * Retrieves the time from the Ably service as milliseconds since the Unix epoch. Clients that do not have access to a sufficiently well maintained time source and wish to issue Ably {@link Types.TokenRequest | `TokenRequest`s} with a more accurate timestamp should use the {@link Types.ClientOptions.queryTime} property instead of this method. * - * @returns A promise which, upon success, will be fulfilled with the time as milliseconds since the Unix epoch. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with the time as milliseconds since the Unix epoch. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ time(): Promise; /** * Publishes a {@link Types.BatchPublishSpec} object to one or more channels, up to a maximum of 100 channels. * * @param spec - A {@link Types.BatchPublishSpec} object. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch publish for each requested channel. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch publish for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPublish(spec: BatchPublishSpec): Promise>; /** * Publishes one or more {@link Types.BatchPublishSpec} objects to one or more channels, up to a maximum of 100 channels. * * @param specs - An array of {@link Types.BatchPublishSpec} objects. - * @returns A promise which, upon success, will be fulfilled with an array of {@link Types.BatchResult} objects containing information about the result of the batch publish for each requested channel for each provided {@link Types.BatchPublishSpec}. This array is in the same order as the provided {@link Types.BatchPublishSpec} array. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with an array of {@link Types.BatchResult} objects containing information about the result of the batch publish for each requested channel for each provided {@link Types.BatchPublishSpec}. This array is in the same order as the provided {@link Types.BatchPublishSpec} array. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPublish( specs: BatchPublishSpec[] @@ -1726,7 +1694,7 @@ declare namespace Types { * Retrieves the presence state for one or more channels, up to a maximum of 100 channels. Presence state includes the `clientId` of members and their current {@link Types.PresenceAction}. * * @param channels - An array of one or more channel names, up to a maximum of 100 channels. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch presence request for each requested channel. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} object containing information about the result of the batch presence request for each requested channel. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ batchPresence(channels: string[]): Promise[]>; /** @@ -1757,7 +1725,7 @@ declare namespace Types { * * @param tokenParams - A {@link TokenParams} object. * @param authOptions - An {@link AuthOptions} object. - * @returns A promise which, upon success, will be fulfilled with a {@link TokenRequest} object. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link TokenRequest} object. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ createTokenRequest(tokenParams?: TokenParams, authOptions?: AuthOptions): Promise; /** @@ -1773,7 +1741,7 @@ declare namespace Types { * * @param specifiers - An array of {@link TokenRevocationTargetSpecifier} objects. * @param options - A set of options which are used to modify the revocation request. - * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} containing information about the result of the token revocation request for each provided [`TokenRevocationTargetSpecifier`]{@link TokenRevocationTargetSpecifier}. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with a {@link Types.BatchResult} containing information about the result of the token revocation request for each provided [`TokenRevocationTargetSpecifier`]{@link TokenRevocationTargetSpecifier}. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ revokeTokens( specifiers: TokenRevocationTargetSpecifier[], @@ -2380,7 +2348,7 @@ declare namespace Types { * Generates a random key to be used in the encryption of the channel. If the language cryptographic randomness primitives are blocking or async, a callback is used. The callback returns a generated binary key. * * @param keyLength - The length of the key, in bits, to be generated. If not specified, this is equal to the default `keyLength` of the default algorithm: for AES this is 256 bits. - * @returns A promise which, upon success, will be fulfilled with the generated key as a binary, for example, a byte array. Upon failure, the promise will be rejected with an {@link Types.ErrorInfo} object which explains the error. + * @returns A promise which, upon success, will be fulfilled with the generated key as a binary, for example, a byte array. Upon failure, the promise will be rejected with an {@link ErrorInfo} object which explains the error. */ generateRandomKey(keyLength?: number): Promise; /** @@ -2725,4 +2693,31 @@ export declare class Realtime extends Types.Realtime { /** * A generic Ably error object that contains an Ably-specific status code, and a generic status code. Errors returned from the Ably server are compatible with the `ErrorInfo` structure and should result in errors that inherit from `ErrorInfo`. */ -export declare class ErrorInfo extends Types.ErrorInfo {} +export declare class ErrorInfo { + /** + * Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json). + */ + code: number; + /** + * Additional message information, where available. + */ + message: string; + /** + * HTTP Status Code corresponding to this error, where applicable. + */ + statusCode: number; + /** + * The underlying cause of the error, where applicable. + */ + cause?: string | Error | ErrorInfo; + + /** + * Construct an ErrorInfo object. + * + * @param message - A string describing the error. + * @param code - Ably [error code](https://github.com/ably/ably-common/blob/main/protocol/errors.json). + * @param statusCode - HTTP Status Code corresponding to this error. + * @param cause - The underlying cause of the error. + */ + constructor(message: string, code: number, statusCode: number, cause?: string | Error | ErrorInfo); +} diff --git a/src/common/lib/types/errorinfo.ts b/src/common/lib/types/errorinfo.ts index f7ed5193b7..86b267159e 100644 --- a/src/common/lib/types/errorinfo.ts +++ b/src/common/lib/types/errorinfo.ts @@ -26,7 +26,7 @@ export interface IConvertibleToErrorInfo { statusCode: number; } -export default class ErrorInfo extends Error implements IPartialErrorInfo, API.Types.ErrorInfo { +export default class ErrorInfo extends Error implements IPartialErrorInfo, API.ErrorInfo { code: number; statusCode: number; cause?: string | Error | ErrorInfo; diff --git a/src/platform/react-hooks/sample-app/src/App.tsx b/src/platform/react-hooks/sample-app/src/App.tsx index fafebf8d3a..aafceb74ec 100644 --- a/src/platform/react-hooks/sample-app/src/App.tsx +++ b/src/platform/react-hooks/sample-app/src/App.tsx @@ -1,4 +1,4 @@ -import { Types } from 'ably'; +import { Types, ErrorInfo } from 'ably'; import React, { useState } from 'react'; import { useChannel, @@ -33,7 +33,7 @@ function App() { const [ablyErr, setAblyErr] = useState(''); const [channelState, setChannelState] = useState(channel.state); const [previousChannelState, setPreviousChannelState] = useState(); - const [channelStateReason, setChannelStateReason] = useState(); + const [channelStateReason, setChannelStateReason] = useState(); useChannelStateListener('your-channel-name', (stateChange) => { setAblyErr(JSON.stringify(stateChange.reason)); @@ -106,7 +106,7 @@ function App() { function ConnectionState() { const ably = useAbly(); const [connectionState, setConnectionState] = useState(ably.connection.state); - const [connectionError, setConnectionError] = useState(null); + const [connectionError, setConnectionError] = useState(null); useConnectionStateListener((stateChange) => { console.log(stateChange); setConnectionState(stateChange.current); diff --git a/src/platform/react-hooks/src/AblyReactHooks.ts b/src/platform/react-hooks/src/AblyReactHooks.ts index 2742f29a7e..1d45ae9ccc 100644 --- a/src/platform/react-hooks/src/AblyReactHooks.ts +++ b/src/platform/react-hooks/src/AblyReactHooks.ts @@ -1,4 +1,4 @@ -import { Types } from '../../../../ably.js'; +import { Types, ErrorInfo } from '../../../../ably.js'; export type ChannelNameAndOptions = { channelName: string; @@ -7,8 +7,8 @@ export type ChannelNameAndOptions = { subscribeOnly?: boolean; skip?: boolean; - onConnectionError?: (error: Types.ErrorInfo) => unknown; - onChannelError?: (error: Types.ErrorInfo) => unknown; + onConnectionError?: (error: ErrorInfo) => unknown; + onChannelError?: (error: ErrorInfo) => unknown; }; export type ChannelNameAndId = { diff --git a/src/platform/react-hooks/src/hooks/useChannel.test.tsx b/src/platform/react-hooks/src/hooks/useChannel.test.tsx index 741d064576..a1f66dcc34 100644 --- a/src/platform/react-hooks/src/hooks/useChannel.test.tsx +++ b/src/platform/react-hooks/src/hooks/useChannel.test.tsx @@ -3,7 +3,7 @@ import { it, beforeEach, describe, expect, vi } from 'vitest'; import { useChannel } from './useChannel.js'; import { render, screen, waitFor } from '@testing-library/react'; import { FakeAblySdk, FakeAblyChannels } from '../fakes/ably.js'; -import { Types } from '../../../../../ably.js'; +import { Types, ErrorInfo } from '../../../../../ably.js'; import { act } from 'react-dom/test-utils'; import { AblyProvider } from '../AblyProvider.js'; @@ -202,8 +202,8 @@ const UseChannelComponent = ({ skip }: { skip?: boolean }) => { }; interface UseChannelStateErrorsComponentProps { - onConnectionError?: (err: Types.ErrorInfo) => unknown; - onChannelError?: (err: Types.ErrorInfo) => unknown; + onConnectionError?: (err: ErrorInfo) => unknown; + onChannelError?: (err: ErrorInfo) => unknown; } const UseChannelStateErrorsComponent = ({ onConnectionError, onChannelError }: UseChannelStateErrorsComponentProps) => { diff --git a/src/platform/react-hooks/src/hooks/useChannel.ts b/src/platform/react-hooks/src/hooks/useChannel.ts index a92958c08e..f6becb3afd 100644 --- a/src/platform/react-hooks/src/hooks/useChannel.ts +++ b/src/platform/react-hooks/src/hooks/useChannel.ts @@ -1,4 +1,4 @@ -import { Types } from '../../../../../ably.js'; +import { Types, ErrorInfo } from '../../../../../ably.js'; import { useEffect, useMemo, useRef } from 'react'; import { channelOptionsWithAgent, ChannelParameters } from '../AblyReactHooks.js'; import { useAbly } from './useAbly.js'; @@ -9,8 +9,8 @@ export type AblyMessageCallback = Types.messageCallback; export interface ChannelResult { channel: Types.RealtimeChannel; ably: Types.Realtime; - connectionError: Types.ErrorInfo | null; - channelError: Types.ErrorInfo | null; + connectionError: ErrorInfo | null; + channelError: ErrorInfo | null; } type SubscribeArgs = [string, AblyMessageCallback] | [AblyMessageCallback]; diff --git a/src/platform/react-hooks/src/hooks/usePresence.test.tsx b/src/platform/react-hooks/src/hooks/usePresence.test.tsx index 8553832a30..659163ba92 100644 --- a/src/platform/react-hooks/src/hooks/usePresence.test.tsx +++ b/src/platform/react-hooks/src/hooks/usePresence.test.tsx @@ -4,7 +4,7 @@ import { usePresence } from './usePresence.js'; import { render, screen, act } from '@testing-library/react'; import { FakeAblySdk, FakeAblyChannels } from '../fakes/ably.js'; import { AblyProvider } from '../AblyProvider.js'; -import { Types } from '../../../../../ably.js'; +import { Types, ErrorInfo } from '../../../../../ably.js'; function renderInCtxProvider(client: FakeAblySdk, children: React.ReactNode | React.ReactNode[]) { return render({children}); @@ -215,8 +215,8 @@ const UsePresenceComponentMultipleClients = () => { }; interface UsePresenceStateErrorsComponentProps { - onConnectionError?: (err: Types.ErrorInfo) => unknown; - onChannelError?: (err: Types.ErrorInfo) => unknown; + onConnectionError?: (err: ErrorInfo) => unknown; + onChannelError?: (err: ErrorInfo) => unknown; } const UsePresenceStateErrorsComponent = ({ diff --git a/src/platform/react-hooks/src/hooks/usePresence.ts b/src/platform/react-hooks/src/hooks/usePresence.ts index c328a6055b..944480203d 100644 --- a/src/platform/react-hooks/src/hooks/usePresence.ts +++ b/src/platform/react-hooks/src/hooks/usePresence.ts @@ -1,4 +1,4 @@ -import { Types } from '../../../../../ably.js'; +import { Types, ErrorInfo } from '../../../../../ably.js'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { channelOptionsWithAgent, ChannelParameters } from '../AblyReactHooks.js'; import { useAbly } from './useAbly.js'; @@ -7,8 +7,8 @@ import { useStateErrors } from './useStateErrors.js'; export interface PresenceResult { presenceData: PresenceMessage[]; updateStatus: (messageOrPresenceObject: T) => void; - connectionError: Types.ErrorInfo | null; - channelError: Types.ErrorInfo | null; + connectionError: ErrorInfo | null; + channelError: ErrorInfo | null; } export type OnPresenceMessageReceived = (presenceData: PresenceMessage) => void; diff --git a/src/platform/react-hooks/src/hooks/useStateErrors.ts b/src/platform/react-hooks/src/hooks/useStateErrors.ts index ff991bb55e..4387bb225e 100644 --- a/src/platform/react-hooks/src/hooks/useStateErrors.ts +++ b/src/platform/react-hooks/src/hooks/useStateErrors.ts @@ -1,12 +1,12 @@ -import { Types } from '../../../../../ably.js'; +import { ErrorInfo } from '../../../../../ably.js'; import { useState } from 'react'; import { useConnectionStateListener } from './useConnectionStateListener.js'; import { useChannelStateListener } from './useChannelStateListener.js'; import { ChannelNameAndOptions } from '../AblyReactHooks.js'; export function useStateErrors(params: ChannelNameAndOptions) { - const [connectionError, setConnectionError] = useState(null); - const [channelError, setChannelError] = useState(null); + const [connectionError, setConnectionError] = useState(null); + const [channelError, setChannelError] = useState(null); useConnectionStateListener( ['suspended', 'failed', 'disconnected'],