import type { ErrorUserFacingDetails, ErrorUserFacingDetailsWithMessage } from "./generated/errors"; import type { ReploErrorConfig } from "./reploError"; import * as z from "zod"; import { ReploError } from "./reploError"; /** * Wraps an error so `async-retry` stops immediately instead of scheduling * another attempt: the library rejects with any thrown error carrying a truthy * `bail` property. Preserves the underlying error's message and keeps it as the * cause so callers still surface the real failure. */ export declare class AsyncRetryBailError extends ReploError { readonly bail = true; constructor(cause: unknown); } export type AuthErrorType = "unauthenticated" | "unauthorized" | "notFound"; export type ReploAuthenticationErrorConfig = { message: string; type: AuthErrorType; userFacingDetails?: ErrorUserFacingDetailsWithMessage; additionalData?: ReploErrorConfig["additionalData"]; cause?: ReploErrorConfig["cause"]; }; export declare class ReploAuthenticationError extends ReploError { type: AuthErrorType; userFacingDetails?: ErrorUserFacingDetailsWithMessage; constructor(config: ReploAuthenticationErrorConfig); getHttpStatusCode(): 401 | 403 | 404; getTRPCErrorCode(): "UNAUTHORIZED" | "FORBIDDEN" | "NOT_FOUND"; } /** * Error which automatically makes all Replo services respond with a specific * HTTP status code when caught. Should only be thrown from routes, makes it * easier to provide a standardized way of implementing user-facing messages */ export declare class ReploHTTPError extends ReploError { userFacingDetails: ErrorUserFacingDetails; statusCode: number; details?: object; constructor(config: ReploErrorConfig & { statusCode: number; userFacingDetails: ErrorUserFacingDetails; details?: object; }); } /** * HTTP error for callers that branch on `key` in code (SDKs, other services) * rather than showing it in Replo's own UI, so it has no display `type`. The * worker error handler answers `{ key, message, details, errorId }`. Should * only be thrown from routes. */ export declare class ReploParseableHTTPError extends ReploError { statusCode: number; key: string; userFacingMessage: string; details?: Record; constructor(config: ReploErrorConfig & { statusCode: number; key: string; userFacingMessage: string; details?: Record; }); } /** * Error used to represent an HTTP error that should be surfaced as such. This * should be thrown when we want to pass the error through without changing the * status code and without providing any user facing details (because this route * is not serving the client e.g. when we're calling Mirror through the * Publisher) */ export declare class ReploRawHTTPError extends ReploError { statusCode: number; errorType: string; data?: object; constructor(config: { statusCode: number; message: string; errorType: string; data?: object; }); } /** * Error which is automatically mapped to a status code response wherever it's * thrown. Errors which are thrown from many different places where we want to * always respond in the same way should inherit this, e.g. an error thrown for * any Shopify call when the user has uninstalled the app. * * Inheriting from this should be uncommon, for most errors we want to inherit * from ReploError and catch/map them to ReploHTTPErrors in our routes. For the * uncommon cases where we want to globally map errors this reduces boilerplate. * * Globally mapped errors are never reported to Sentry or logged. */ export declare class Uncommon_GloballyMappedError extends ReploError { userFacingDetails: ErrorUserFacingDetails; statusCode: number; constructor(config: ReploErrorConfig & { statusCode: number; userFacingDetails: ErrorUserFacingDetails; }); } /** * The `userFacingDetails.key` publisher puts on its 404 for a missing project. * It lives here rather than next to the error class because a caller across a * service boundary (airlock) matches on it to tell "this project is gone" apart * from any other 404 that URL could produce. */ export declare const PROJECT_NOT_FOUND_ERROR_KEY = "errors.project.notFound"; export declare class ReploValidationError extends ReploError { constructor(message: string); } export declare class UnexpectedMutationError extends ReploError { constructor(); } export declare class UnexpectedRawGraphqlClientError extends ReploError { originalError: unknown; errors: unknown[]; data: unknown; constructor(opts: { originalError: unknown; errors: unknown[]; data: unknown; }); } export declare const DEFAULT_ERROR_MESSAGE_CONFIG: { header: string; message: string; isFullPage: boolean; }; export type ErrorDetails = { header: string; subheader?: string; message?: string | string[] | React.ReactNode; messageDetail?: string; isRecoverable?: boolean; isFullPage?: boolean; usage?: { current: number; maximum: number; }; callToAction?: { type: "installApp"; } | { type: "callback"; name: string; onClick(): void; } | { type: "link"; name: string; to: string; target?: string; } | { type: "closeModal"; name: string; } | { type: "navigate"; location: { type: "integrationHub"; } | { type: "home"; } | { type: "workspace"; workspaceId: string; workspaceName: string; }; } | { type: "custom"; callToActionType: ErrorUserFacingDetailsWithMessage["callToAction"]; }; }; /** * Map of error keys to custom user-facing details. Should ONLY be used * in cases where we want to override the default behavior of ErrorUserFacingDetails * from the backend. */ export declare const CUSTOM_ERROR_KEY_TO_PROPS: { "shopifyArticle.failedToPublish": () => { header: string; message: string; }; "shopifySection.failedToPublish": () => { header: string; message: string; }; "page.failedToPublish": () => { header: string; message: string; }; "shopifyProductTemplate.failedToPublish": () => { header: string; message: string; }; "element.failedToPublish": () => { header: string; message: string; }; "element.failedToUpdate": () => { header: string; message: string; }; "store.billingPlan.alreadyExist": () => { header: string; message: string; }; "error.assets.unsupportedFileType": ({ serverMessage }: { type: string; serverMessage?: string; endpoint: string | null; }) => { header: string; message: string; }; "error.assets.fileTooLarge": () => { header: string; message: string; }; "error.files.fileTooLarge": () => { header: string; message: string; }; base: () => { header: string; message: string; isFullPage: boolean; }; }; export declare function extractErrorId(error: unknown): string | undefined; export declare function addErrorIdIfNeeded(error: unknown): void; export declare const errorUserFacingDetailsMessageSchema: z.ZodObject<{ type: z.ZodEnum<{ toast: "toast"; fullPageModal: "fullPageModal"; shopifyStorePassword: "shopifyStorePassword"; "billing.addPublishedElements": "billing.addPublishedElements"; "billing.addShopifyThemeProject": "billing.addShopifyThemeProject"; "billing.addReploSite": "billing.addReploSite"; "agentBilling.shopifyThemeBuilder.publishedElements.exceeded": "agentBilling.shopifyThemeBuilder.publishedElements.exceeded"; "agentBilling.shopifyThemeBuilder.projects.exceeded": "agentBilling.shopifyThemeBuilder.projects.exceeded"; "agentBilling.sites.exceeded": "agentBilling.sites.exceeded"; "agentBilling.credits.exceeded": "agentBilling.credits.exceeded"; "agentBilling.upgradeRequired": "agentBilling.upgradeRequired"; }>; message: z.ZodString; isRecoverable: z.ZodOptional; detail: z.ZodOptional, z.ZodString]>>; key: z.ZodString; details: z.ZodOptional>; usage: z.ZodOptional>; plan: z.ZodOptional; callToAction: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"installApp">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"goToHomepage">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"navigateToProjectEditor">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"closeModal">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"navigateToLink">; link: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: z.ZodLiteral<"errors.wrongJsonExtension">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.chunkingError">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.indexBackupError">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.shopifyIntegrationAlreadyAssigned">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.shopifyIntegrationMissingAccessScopes">; url: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"customLink">; url: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.projectConnectedToBillingIntegrationForShopifyWorkspace">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.themeAssetSizeLimitExceeded">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.themeTotalSizeLimitExceeded">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.pageMetafieldDefinitionsChanged">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"settings.billing">; }, z.core.$strip>], "type">; }, z.core.$strip>], "type">>; }, z.core.$strip>; /** * Schema for user-facing details which the frontend uses to show toasts, modals, etc * when an error is thrown from the backend */ export declare const errorUserFacingDetailsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: z.ZodEnum<{ toast: "toast"; fullPageModal: "fullPageModal"; shopifyStorePassword: "shopifyStorePassword"; "billing.addPublishedElements": "billing.addPublishedElements"; "billing.addShopifyThemeProject": "billing.addShopifyThemeProject"; "billing.addReploSite": "billing.addReploSite"; "agentBilling.shopifyThemeBuilder.publishedElements.exceeded": "agentBilling.shopifyThemeBuilder.publishedElements.exceeded"; "agentBilling.shopifyThemeBuilder.projects.exceeded": "agentBilling.shopifyThemeBuilder.projects.exceeded"; "agentBilling.sites.exceeded": "agentBilling.sites.exceeded"; "agentBilling.credits.exceeded": "agentBilling.credits.exceeded"; "agentBilling.upgradeRequired": "agentBilling.upgradeRequired"; }>; message: z.ZodString; isRecoverable: z.ZodOptional; detail: z.ZodOptional, z.ZodString]>>; key: z.ZodString; details: z.ZodOptional>; usage: z.ZodOptional>; plan: z.ZodOptional; callToAction: z.ZodOptional; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"installApp">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"goToHomepage">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"navigateToProjectEditor">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"closeModal">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"navigateToLink">; link: z.ZodDiscriminatedUnion<[z.ZodObject<{ type: z.ZodLiteral<"errors.wrongJsonExtension">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.chunkingError">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.indexBackupError">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.shopifyIntegrationAlreadyAssigned">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.shopifyIntegrationMissingAccessScopes">; url: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"customLink">; url: z.ZodString; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.projectConnectedToBillingIntegrationForShopifyWorkspace">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.themeAssetSizeLimitExceeded">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.themeTotalSizeLimitExceeded">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"errors.pageMetafieldDefinitionsChanged">; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"settings.billing">; }, z.core.$strip>], "type">; }, z.core.$strip>], "type">>; }, z.core.$strip>, z.ZodObject<{ type: z.ZodLiteral<"uncommon_none">; key: z.ZodString; usage: z.ZodOptional>; message: z.ZodOptional; isRecoverable: z.ZodOptional; detail: z.ZodOptional, z.ZodString]>>; }, z.core.$strip>], "type">; export declare const extractErrorTrackingEventDetails: (error: unknown, transaction: string | undefined, tags?: Record) => { fingerprint: string[]; extra: { zodIssues: z.core.$ZodIssue[]; cause?: undefined; }; tags: { errorId?: string | undefined; }; } | { fingerprint: string[]; extra: Record | undefined; tags: { errorId: string; }; } | { extra: { cause: unknown; zodIssues?: undefined; }; tags: { errorId?: string | undefined; }; fingerprint?: undefined; } | { tags: { errorId?: string | undefined; }; fingerprint?: undefined; extra?: undefined; } | null; export declare const shouldReportErrorToSentry: (error: Error) => boolean; export declare class CloudflareAgentCoordinatorRpcError extends ReploError { constructor(error: unknown); } /** * Failures on the shared iframe RPC channel (miniapp ↔ parent, canopy ↔ WB). * Live next to other domain errors so callers get ReploError reporting without * a `replo-utils → schemas` workspace cycle (schemas already depends on * replo-utils; the channel implementation lives in `schemas/iframeRpcChannel`). */ export declare abstract class IframeRpcChannelError extends ReploError { } export declare class IframeRpcChannelTimeoutError extends IframeRpcChannelError { constructor({ method, timeoutMs }: { method: string; timeoutMs: number; }); } export declare class IframeRpcChannelTargetUnavailableError extends IframeRpcChannelError { constructor({ callType, method, }: { callType: "notify" | "request" | "response"; method?: string; }); } export declare class IframeRpcChannelRemoteError extends IframeRpcChannelError { constructor({ method, message }: { method: string; message: string; }); } export declare class IframeRpcChannelUnsubscribedError extends IframeRpcChannelError { constructor({ method }: { method: string; }); } export declare class IframeRpcChannelUnknownMethodError extends IframeRpcChannelError { constructor({ method }: { method: string; }); } export declare class IframeRpcChannelConfigurationError extends IframeRpcChannelError { constructor({ message }: { message: string; }); } export declare class IframeRpcChannelInvalidInputError extends IframeRpcChannelError { constructor({ method, cause }: { method: string; cause: z.ZodError; }); }