Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: UpdateException: error decoding response body, reason: unknown #2916

Open
msalman-mufin opened this issue Feb 21, 2025 · 10 comments
Open
Assignees
Labels
question Further information is requested waiting for response Waiting for customer response

Comments

@msalman-mufin
Copy link

msalman-mufin commented Feb 21, 2025

App ID: 5be7858a-e211-44f2-8120-5d21ce6bf5eb

Description

We are getting lot of these exception upon calling await codePush.update(track: _currentTrack);
Exception:
Fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Instance of 'UpdateException' at ShorebirdUpdaterImpl.update(shorebird_updater_io.dart:116) at _RestartWidgetState.updateWatcher(restart_widget.dart:86)
UpdateException: error decoding response body, reason: unknown ^

Expected Behavior

We are getting this exception in hundreds of numbers, let us know if is that a suppose to happens or is this a issue.

Additional Context
In case if this info required...

  • shorebird_code_push: ^2.0.2
  • auto_update: false
@msalman-mufin msalman-mufin added the bug Something isn't working label Feb 21, 2025
@felangel
Copy link
Contributor

felangel commented Feb 21, 2025

Hi @msalman-mufin 👋
Thanks for filing an issue! Can you share how you are invoking await codePush.update(track: _currentTrack);?
Are you first checking whether an update is available via codePush.checkForUpdate();?

For reference we recommend the following usage:

final updater = ShorebirdUpdater();

Future<void> updateIfAvailable() async {
  try {
    // Check if there's an update available first.
    final status = await updater.checkForUpdate();
    final updateAvailable = status == UpdateStatus.outdated;
    // Only call `update` if there is an update available.
    if (updateAvailable) await updater.update();
  } on Exception catch (e) {
    // Handle any exceptions.
    if (e is UpdateException) {
      // Here you have access to the update failure reason
    }
  }
}

You should be able to catch the update exception and see why the update failed like:

try {
  await codePush.update(track: _currentTrack);
} on UpdateException catch (e) {
  print(e.message); // See the human readable message
  print(e.failureReason); // See failure reason
}

The failure reason can be one of the following:

enum UpdateFailureReason {
  /// No update is available.
  noUpdate,

  /// The update failed because the patch could not be downloaded.
  downloadFailed,

  /// The update failed because the patch failed to install.
  installFailed,

  /// The update failed for an unknown reason.
  unknown,
}

Some of the most common failure reasons are:

  • noUpdate: This means you're calling update when there are no new patches available
  • downloadFailed: This means the device was unable to successfully download the patch (network-related)

Hope that helps!

@felangel felangel added question Further information is requested waiting for response Waiting for customer response and removed bug Something isn't working labels Feb 21, 2025
@felangel felangel self-assigned this Feb 21, 2025
@msalman-mufin
Copy link
Author

@felangel Here is the code that we are using

ShorebirdUpdater codePush = ShorebirdUpdater();
  Future<void> updateWatcher(timer) async {
    try {
      final status = await codePush.checkForUpdate(track: _currentTrack);
      switch (status) {
        case UpdateStatus.outdated:
          logUserEvent(eventName: 'patch_ready', data: analyticsParams);
          checker?.cancel();
          logUserEvent(eventName: 'starting_patch_download', data: analyticsParams);
          await codePush.update(track: _currentTrack);
          logUserEvent(eventName: 'patch_downloaded', data: analyticsParams);
          setupRestart();
          checker = Timer.periodic(10.seconds, updateWatcher);
          break;
        case UpdateStatus.restartRequired:
          logUserEvent(eventName: 'patch_ready_already', data: analyticsParams);
          setupRestart();
          break;
        // case UpdateStatus.unavailable:
        // // Do nothing, there is already a warning displayed at the top of the
        // // screen.
        default:
          checker?.cancel();
          checker = Timer.periodic(1.minutes, updateWatcher);
      }
    } catch (error, s) {
      var extraInfo = '';
      watcherExceptionCount++;
      if(error is ReadPatchException) {
        extraInfo = 'ReadPatchException: ${error.message}';
      } else if(error is UpdateException) {
        extraInfo = 'UpdateException: ${error.message}, reason: ${error.reason.name}';
      }

      if (watcherExceptionCount > 3) {
        recordCrashEvent(
            Exception('Got third time, aborting update watcher, E: $error'),
            s,
          moreData: extraInfo,
          reason: 'updated watcher three times failed'
        );
        checker?.cancel();
      } else {
        recordCrashEvent(
            error, s,
          moreData: extraInfo,
          reason: 'updated watcher failed'
        );
      }
    }
  }

  • I think we are covering the noUpdate part, please let me know more what you think

@felangel
Copy link
Contributor

@msalman-mufin yup looks like you're covering the no update case. Can you share what the following log is:

extraInfo = 'UpdateException: ${error.message}, reason: ${error.reason.name}';

This should give us more information about why the update is failing.

@msalman-mufin
Copy link
Author

@felangel that log is the title of this issue 'UpdateException: error decoding response body, reason: unknown'

@msalman-mufin
Copy link
Author

@felangel More insights...
Currently we are using shorebird_code_push: ^2.0.2 but before we were using shorebird_code_push: ^1.1.3 and there was no such problems.

@felangel
Copy link
Contributor

@felangel that log is the title of this issue 'UpdateException: error decoding response body, reason: unknown'

That means you’re using an older flutter version (and updater) which doesn’t have the ability to report a failure reason. Are you able to re-release with the latest stable flutter version and re-test?

@msalman-mufin
Copy link
Author

@felangel currently we are using ^3.27.3 and the latest flutter available is 3.29.0, so if we update this version will it resolve this issue or we will just get report of failure ?

@felangel
Copy link
Contributor

@felangel currently we are using ^3.27.3 and the latest flutter available is 3.29.0, so if we update this version will it resolve this issue or we will just get report of failure ?

If you update you’ll just have more information about why an update failed to install. The most common reasons are networking related (e.g timeouts due to poor connections, ISP blocking our cdn, etc.)

@ismail-mufin
Copy link

Hi! @felangel
We have been using Shorebird for a long time, we understood your approach of continuously upgrading and discontinuing support for previous versions during the beta. However, Shorebird is now a stable product, and shouldn't it provide support and issue resolution for every Flutter version it supports?

3.27.3 is not an old Flutter version, it was released only 1 month ago. Updating the Flutter version requires a new release on the market, which we already use Shorebird to avoid.

@felangel
Copy link
Contributor

felangel commented Feb 25, 2025

Hi! @felangel We have been using Shorebird for a long time, we understood your approach of continuously upgrading and discontinuing support for previous versions during the beta. However, Shorebird is now a stable product, and shouldn't it provide support and issue resolution for every Flutter version it supports?

I totally understand your perspective and apologize for the inconvenience! We mainly haven't been back-porting our fixes because we are still a tiny team and it would be very costly for us at this stage.

3.27.3 is not an old Flutter version, it was released only 1 month ago. Updating the Flutter version requires a new release on the market, which we already use Shorebird to avoid.

Even if we back-ported this fix, it'd still require you to re-release with a new revision of Flutter since the fix required making changes to our updater which is integrated into the Flutter engine. These are native code changes that can't be applied via a patch unfortunately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested waiting for response Waiting for customer response
Projects
None yet
Development

No branches or pull requests

3 participants