import type { Class } from '../types.js';
import type { BackendErrorResponseObject, ErrorData, ErrorLike, ErrorObject, HttpRequestErrorData } from './error.model.js';
/**
 * Useful to ensure that error in `catch (err) { ... }`
 * is indeed an Error (and not e.g `string` or `undefined`).
 * 99% of the cases it will be Error already.
 * Becomes more useful since TypeScript 4.4 made `err` of type `unknown` by default.
 *
 * Alternatively, if you're sure it's Error - you can use `_assertIsError(err)`.
 */
export declare function _anyToError<ERROR_TYPE extends Error = Error>(o: any, errorClass?: Class<ERROR_TYPE>, errorData?: ErrorData): ERROR_TYPE;
/**
 * Converts "anything" to ErrorObject.
 * Detects if it's HttpErrorResponse, HttpErrorObject, ErrorObject, Error, etc..
 * If object is Error - Error.message will be used.
 * Objects (not Errors) get converted to prettified JSON string (via `_stringify`).
 */
export declare function _anyToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(o: any, errorData?: Partial<DATA_TYPE>): ErrorObject<DATA_TYPE>;
export declare function _errorLikeToErrorObject<DATA_TYPE extends ErrorData = ErrorData>(e: AppError<DATA_TYPE> | Error | ErrorLike): ErrorObject<DATA_TYPE>;
export declare function _errorObjectToError<DATA_TYPE extends ErrorData, ERROR_TYPE extends Error>(o: ErrorObject<DATA_TYPE>, errorClass?: Class<ERROR_TYPE>): ERROR_TYPE;
export interface ErrorSnippetOptions {
    /**
     * Max length of the error line.
     * Snippet may have multiple lines, one original and one per `cause`.
     */
    maxLineLength?: number;
    maxLines?: number;
}
/**
 * Provides a short semi-user-friendly error message snippet,
 * that would allow to give a hint to the user what went wrong,
 * also to developers and CS to distinguish between different errors.
 *
 * It's not supposed to have full information about the error, just a small extract from it.
 */
export declare function _errorSnippet(err: any, opt?: ErrorSnippetOptions): string;
export declare function _isBackendErrorResponseObject(o: any): o is BackendErrorResponseObject;
export declare function _isHttpRequestErrorObject(o: any): o is ErrorObject<HttpRequestErrorData>;
/**
 * Note: any instance of AppError is also automatically an ErrorObject
 */
export declare function _isErrorObject<DATA_TYPE extends ErrorData = ErrorData>(o: any): o is ErrorObject<DATA_TYPE>;
export declare function _isErrorLike(o: any): o is ErrorLike;
/**
 * Convenience function to safely add properties to Error's `data` object
 * (even if it wasn't previously existing).
 * Mutates err.
 * Returns err for convenience, so you can re-throw it directly.
 *
 * @example
 *
 * try {} catch (err) {
 *   throw _errorDataAppend(err, {
 *     backendResponseStatusCode: 401,
 *   })
 * }
 */
export declare function _errorDataAppend<ERR, OUT extends Error = ERR extends Error ? ERR : Error>(err: ERR, data?: ErrorData): OUT;
export interface AppErrorComponents<DATA_TYPE extends ErrorData = ErrorData> {
    message: string;
    name?: string;
    data?: DATA_TYPE;
    cause?: any;
}
/**
 * Extra options for AppError constructor.
 */
export interface AppErrorOptions {
    /**
     * Overrides Error.name and Error.constructor.name
     */
    name?: string;
    /**
     * Sets Error.cause.
     * It is transformed with _anyToErrorObject()
     */
    cause?: any;
}
/**
 * Base class for all our (not system) errors.
 *
 * message - "technical" message. Frontend decides to show it or not.
 * data - optional "any" payload.
 * data.userFriendly - if present, will be displayed to the User as is.
 *
 * Based on: `https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801`
 */
export declare class AppError<DATA_TYPE extends ErrorData = ErrorData> extends Error {
    data: DATA_TYPE;
    /**
     * `cause` here is normalized to be an ErrorObject
     */
    cause?: ErrorObject;
    /**
     * Experimental alternative static constructor.
     */
    static of<DATA_TYPE extends ErrorData = ErrorData>(opt: AppErrorComponents): AppError<DATA_TYPE>;
    constructor(message: string, data?: DATA_TYPE, opt?: AppErrorOptions);
}
/**
 * Error that is thrown when Http Request was made and returned an error.
 * Thrown by, for example, Fetcher.
 *
 * On the Frontend this Error class represents the error when calling the API,
 * contains all the necessary request and response information.
 *
 * On the Backend, similarly, it represents the error when calling some 3rd-party API
 * (backend-to-backend call).
 * On the Backend it often propagates all the way to the Backend error handler,
 * where it would be wrapped in BackendErrorResponseObject.
 *
 * Please note that `ErrorData.backendResponseStatusCode` is NOT exactly the same as
 * `HttpRequestErrorData.responseStatusCode`.
 * E.g 3rd-party call may return 401, but our Backend will still wrap it into an 500 error
 * (by default).
 */
export declare class HttpRequestError extends AppError<HttpRequestErrorData> {
    constructor(message: string, data: HttpRequestErrorData, opt?: AppErrorOptions);
    /**
     * Cause is strictly-defined for HttpRequestError,
     * so it always has a cause.
     * (for dev convenience)
     */
    cause: ErrorObject;
}
export declare class AssertionError extends AppError {
    constructor(message: string, data?: ErrorData);
}
export interface JsonParseErrorData extends ErrorData {
    /**
     * Original text that failed to get parsed.
     */
    text?: string;
}
export declare class JsonParseError extends AppError<JsonParseErrorData> {
    constructor(data: JsonParseErrorData);
}
export declare class TimeoutError extends AppError {
    constructor(message: string, data?: ErrorData, opt?: AppErrorOptions);
}
/**
 * It is thrown when Error was expected, but didn't happen
 * ("pass" happened instead).
 * "Pass" means "no error".
 */
export declare class UnexpectedPassError extends AppError {
    constructor(message?: string);
}
