expandShortUrl static method

Future<String?> expandShortUrl(
  1. String shortUrl
)

Expands a shortened Google Maps URL with caching support.

This method expands shortened URLs (like goo.gl or maps.app.goo.gl) to their full Google Maps URLs. Results are cached to improve performance for repeated requests.

Returns the expanded URL if successful, null if expansion fails.

Throws UrlExpansionException if the URL is invalid or expansion fails.

Example usage:

try {
  final expandedUrl = await GoogleMapsUrlExtractor.expandShortUrl(shortUrl);
  if (expandedUrl != null) {
    print('Expanded URL: $expandedUrl');
  }
} catch (e) {
  print('Error: $e');
}

Implementation

static Future<String?> expandShortUrl(String shortUrl) async {
  // Check cache first
  final cachedUrl = _cache.get('expanded_$shortUrl');
  if (cachedUrl != null) {
    return cachedUrl as String;
  }

  try {
    // Validate URL format
    if (!_isValidShortUrl(shortUrl)) {
      throw const InvalidUrlException('Invalid short URL format');
    }

    final client = http.Client();
    try {
      final request = http.Request('GET', Uri.parse(shortUrl))
        ..followRedirects = false;
      final response = await client.send(request);

      if (response.statusCode == 301 || response.statusCode == 302) {
        final location = response.headers['location'];
        if (location != null) {
          // Cache the result
          _cache.put('expanded_$shortUrl', location);
          return location;
        } else {
          throw const UrlExpansionException(
              'No location header in redirect response');
        }
      } else {
        throw UrlExpansionException(
            'Unexpected response code: ${response.statusCode}');
      }
    } finally {
      client.close();
    }
  } on InvalidUrlException {
    rethrow;
  } on UrlExpansionException {
    rethrow;
  } catch (e) {
    throw UrlExpansionException('Failed to expand URL: $e');
  }
}