{"version":3,"sources":["../../../tools/browser/errors.ts"],"sourcesContent":["/**\n * Custom error classes for browser automation and profiles.\n *\n * @example\n * ```typescript\n * try {\n *   await morph.browser.profiles.createProfile({ name: '', repoId: 'owner/repo' });\n * } catch (e) {\n *   if (e instanceof MorphValidationError) {\n *     console.log('Validation failed:', e.field, e.message);\n *   } else if (e instanceof MorphAPIError) {\n *     console.log('API error:', e.code, e.statusCode);\n *   }\n * }\n * ```\n */\n\n/**\n * Error codes for Morph Browser SDK\n */\nexport type MorphErrorCode =\n  // Validation errors\n  | 'validation_error'\n  | 'invalid_parameter'\n  | 'missing_required_field'\n  // Authentication errors\n  | 'authentication_required'\n  | 'invalid_api_key'\n  | 'insufficient_permissions'\n  // Resource errors\n  | 'profile_not_found'\n  | 'session_not_found'\n  | 'resource_not_found'\n  // Limit errors\n  | 'profile_limit_exceeded'\n  | 'rate_limit_exceeded'\n  // Session errors\n  | 'session_expired'\n  | 'session_save_failed'\n  // Network errors\n  | 'network_error'\n  | 'timeout'\n  | 'service_unavailable';\n\n/**\n * Base error class for all Morph SDK errors.\n */\nexport class MorphError extends Error {\n  /** Error code for programmatic handling */\n  readonly code: MorphErrorCode;\n  /** Original cause of the error, if any */\n  readonly cause?: Error;\n\n  constructor(message: string, code: MorphErrorCode, cause?: Error) {\n    super(message);\n    this.name = 'MorphError';\n    this.code = code;\n    this.cause = cause;\n\n    // Maintains proper stack trace in V8 environments\n    if (Error.captureStackTrace) {\n      Error.captureStackTrace(this, this.constructor);\n    }\n  }\n\n  /**\n   * Returns a JSON representation of the error for logging.\n   */\n  toJSON() {\n    return {\n      name: this.name,\n      message: this.message,\n      code: this.code,\n      cause: this.cause?.message,\n    };\n  }\n}\n\n/**\n * Error thrown when API request validation fails.\n */\nexport class MorphValidationError extends MorphError {\n  /** The field that failed validation */\n  readonly field?: string;\n\n  constructor(message: string, field?: string) {\n    super(message, 'validation_error');\n    this.name = 'MorphValidationError';\n    this.field = field;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      field: this.field,\n    };\n  }\n}\n\n/**\n * Error thrown when an API request fails.\n */\nexport class MorphAPIError extends MorphError {\n  /** HTTP status code */\n  readonly statusCode: number;\n  /** Request ID for debugging (if available) */\n  readonly requestId?: string;\n  /** Raw response body */\n  readonly rawResponse?: string;\n\n  constructor(\n    message: string,\n    code: MorphErrorCode,\n    statusCode: number,\n    options?: {\n      requestId?: string;\n      rawResponse?: string;\n      cause?: Error;\n    }\n  ) {\n    super(message, code, options?.cause);\n    this.name = 'MorphAPIError';\n    this.statusCode = statusCode;\n    this.requestId = options?.requestId;\n    this.rawResponse = options?.rawResponse;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      statusCode: this.statusCode,\n      requestId: this.requestId,\n    };\n  }\n}\n\n/**\n * Error thrown when authentication fails.\n */\nexport class MorphAuthenticationError extends MorphAPIError {\n  constructor(message: string = 'Authentication required. Please provide a valid API key.') {\n    super(message, 'authentication_required', 401);\n    this.name = 'MorphAuthenticationError';\n  }\n}\n\n/**\n * Error thrown when rate limit is exceeded.\n */\nexport class MorphRateLimitError extends MorphAPIError {\n  /** When the rate limit resets (Unix timestamp) */\n  readonly resetAt?: number;\n  /** Number of seconds until reset */\n  readonly retryAfter?: number;\n\n  constructor(\n    message: string = 'Rate limit exceeded. Please retry later.',\n    options?: {\n      resetAt?: number;\n      retryAfter?: number;\n      requestId?: string;\n    }\n  ) {\n    super(message, 'rate_limit_exceeded', 429, { requestId: options?.requestId });\n    this.name = 'MorphRateLimitError';\n    this.resetAt = options?.resetAt;\n    this.retryAfter = options?.retryAfter;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      resetAt: this.resetAt,\n      retryAfter: this.retryAfter,\n    };\n  }\n}\n\n/**\n * Error thrown when a resource is not found.\n */\nexport class MorphNotFoundError extends MorphAPIError {\n  /** The type of resource that was not found */\n  readonly resourceType: string;\n  /** The ID of the resource that was not found */\n  readonly resourceId?: string;\n\n  constructor(resourceType: string, resourceId?: string) {\n    const message = resourceId\n      ? `${resourceType} '${resourceId}' not found`\n      : `${resourceType} not found`;\n    super(message, 'resource_not_found', 404);\n    this.name = 'MorphNotFoundError';\n    this.resourceType = resourceType;\n    this.resourceId = resourceId;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      resourceType: this.resourceType,\n      resourceId: this.resourceId,\n    };\n  }\n}\n\n/**\n * Error thrown when profile limit is exceeded.\n */\nexport class MorphProfileLimitError extends MorphAPIError {\n  /** Current number of profiles */\n  readonly currentCount?: number;\n  /** Maximum allowed profiles for the plan */\n  readonly maxAllowed?: number;\n\n  constructor(\n    message: string = 'Profile limit exceeded for your plan.',\n    options?: {\n      currentCount?: number;\n      maxAllowed?: number;\n      requestId?: string;\n    }\n  ) {\n    super(message, 'profile_limit_exceeded', 403, { requestId: options?.requestId });\n    this.name = 'MorphProfileLimitError';\n    this.currentCount = options?.currentCount;\n    this.maxAllowed = options?.maxAllowed;\n  }\n\n  toJSON() {\n    return {\n      ...super.toJSON(),\n      currentCount: this.currentCount,\n      maxAllowed: this.maxAllowed,\n    };\n  }\n}\n\n/**\n * Parse an API error response and return the appropriate error class.\n */\nexport function parseAPIError(\n  statusCode: number,\n  responseText: string,\n  requestId?: string\n): MorphAPIError {\n  // Try to parse JSON error response\n  let errorData: { detail?: string; code?: string; message?: string } = {};\n  try {\n    errorData = JSON.parse(responseText);\n  } catch {\n    // Not JSON, use raw text\n  }\n\n  const message = errorData.detail || errorData.message || responseText || 'Unknown error';\n  const code = errorData.code;\n\n  // Map status codes to specific error classes\n  switch (statusCode) {\n    case 401:\n      return new MorphAuthenticationError(message);\n\n    case 403:\n      if (code === 'profile_limit_exceeded' || message.toLowerCase().includes('limit')) {\n        return new MorphProfileLimitError(message, { requestId });\n      }\n      return new MorphAPIError(message, 'insufficient_permissions', statusCode, { requestId, rawResponse: responseText });\n\n    case 404:\n      if (message.toLowerCase().includes('profile')) {\n        return new MorphNotFoundError('Profile', undefined);\n      }\n      if (message.toLowerCase().includes('session')) {\n        return new MorphNotFoundError('Session', undefined);\n      }\n      return new MorphAPIError(message, 'resource_not_found', statusCode, { requestId, rawResponse: responseText });\n\n    case 429:\n      return new MorphRateLimitError(message, { requestId });\n\n    case 422:\n      return new MorphAPIError(message, 'validation_error', statusCode, { requestId, rawResponse: responseText });\n\n    case 500:\n    case 502:\n    case 503:\n    case 504:\n      return new MorphAPIError(message, 'service_unavailable', statusCode, { requestId, rawResponse: responseText });\n\n    default:\n      return new MorphAPIError(message, 'network_error', statusCode, { requestId, rawResponse: responseText });\n  }\n}\n"],"mappings":"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","names":[]}