MisarMailPlanLimitError.from constructor

MisarMailPlanLimitError.from(
  1. int status,
  2. Map<String, dynamic> body,
  3. Map<String, String> headers
)

Build from a decoded body plus the response headers. Headers are authoritative; the offer body is the fallback when a proxy strips them.

Implementation

factory MisarMailPlanLimitError.from(
  int status,
  Map<String, dynamic> body,
  Map<String, String> headers,
) {
  final h = {for (final e in headers.entries) e.key.toLowerCase(): e.value};
  final offer = body['upgrade'] is Map<String, dynamic>
      ? body['upgrade'] as Map<String, dynamic>
      : const <String, dynamic>{};
  final urls = offer['urls'];
  final current = offer['current_plan'];
  final retry = h['retry-after'];

  return MisarMailPlanLimitError(
    status,
    (body['error'] as String?) ?? 'plan limit exceeded',
    plan: h['x-misar-plan'] ??
        offer['currentPlanSlug'] as String? ??
        (current is Map<String, dynamic> ? current['slug'] as String? : null),
    upgradeUrl: h['x-misar-upgrade-url'] ??
        (urls is Map<String, dynamic> ? urls['pricing'] as String? : null),
    retryAfter: retry == null ? null : int.tryParse(retry),
    feature: offer['feature'] as String?,
  );
}