0

I keep facing same error seeing logs of firebase crashlytics.

.jsonDecode FormatException: Unexpected end of input (at character 1) ^. Error thrown .

.jsonDecode (dart:convert) JsonCacheInfoRepository._readFile (json_cache_info_repository.dart:143) JsonCacheInfoRepository.open (json_cache_info_repository.dart:40) _WebSocketConsumer.close.. (dart:_http) CacheStore._getCacheDataFromDatabase (cache_store.dart:112) CacheStore.retrieveCacheData. (cache_store.dart:73)

As you can see from thread of this error, it points to cache part.

I use data as decoding it from shared preference:

Future<dynamic> requestCacheDioDiaryGroup(
    String uri, int page, Map<String, dynamic> requestBody) async {
  try {
    final uriKey = "$uri-$page";

    bool exists = SharedPrefsHelper.prefs.containsKey(uriKey);

    if (exists) {
      final data = SharedPrefsHelper.prefs.getString(uriKey);
      if (data != null) {
        return jsonDecodeSafe(data);
      }
    } else {
      String requestBodyJson = jsonEncode(requestBody);
      final tokenHeaders = await firebaseTokenHeaders();

      final response = await http.post(
        Uri.parse(uri),
        body: requestBodyJson,
        headers: tokenHeaders,
      );

      if (response.statusCode == 200) {
        Map<String, dynamic> data =
            jsonDecodeSafe(utf8.decode(response.bodyBytes));

        final diary = data["data"];

        // prefs 저장
        final jsonList = jsonEncode(diary);
        await SharedPrefsHelper.prefs.setString(uriKey, jsonList);
        return diary;
      }
    }
  } catch (e) {
    // ignore: avoid_print
    print("[dio] requestCacheDioDiaryGroup error: $e");
  }
}

And I used jsonDecodeSafe code, not general jsonDecode due to this error:


T jsonDecodeSafe<T>(String? source,
    {String tag = "json_tag", int sample = 120}) {
  try {
    final s = source?.trim();
    if (s == null || s.isEmpty) {
      FirebaseCrashlytics.instance
          .log('[jsonDecodeSafeSafe] EMPTY_INPUT tag=$tag');
      FirebaseCrashlytics.instance.setCustomKey('json_tag', tag);
      FirebaseCrashlytics.instance.setCustomKey('json_len', s?.length ?? 0);
      FirebaseCrashlytics.instance
          .setCustomKey('json_sample', (s ?? '').substring(0, 0));
      throw const FormatException('Empty JSON input');
    }
    // 간혹 UTF-8 디코딩 이슈/잘린 바디 방지용
    final decoded = json.decode(s);
    return decoded as T;
  } catch (e, st) {
    // 앞부분 샘플만 남겨서 개인정보/대용량 로그 방지
    final sampleStr = (source ?? '').replaceAll('\n', ' ');
    FirebaseCrashlytics.instance.setCustomKey('json_tag', tag);
    FirebaseCrashlytics.instance.setCustomKey('json_len', source?.length ?? 0);
    FirebaseCrashlytics.instance.setCustomKey('json_sample',
        sampleStr.substring(0, sample.clamp(0, sampleStr.length)));
    FirebaseCrashlytics.instance
        .recordError(e, st, reason: 'jsonDecodeSafeSafe failed ($tag)');
    rethrow; // Crashlytics에 남긴 뒤 원래 흐름 유지(또는 적절히 처리)
  }
}

I changed all jsonDecode to jsonDecodeSafe in my project in order to prevent this error.

However users keep facing this error.

0

1 Answer 1

1

I encountered the same issue before, where jsonDecode() was throwing a FormatException because the string I passed wasn't valid json. After validating it using json Formatter & Validator, https://jsonformatter.curiousconcept.com/#, I realized the structure was malformed (missing quotes or braces). Once I corrected the format, the error was resolved.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.