Repository: wagtail/wagtail
File: client/src/controllers/UpgradeController.ts (TypeScript)

Code before:
    currentVersion: String,
    ltsOnly: { default: false, type: Boolean },
    url: { default: 'https://releases.wagtail.org/latest.txt', type: String },
  };

  currentVersionValue: string;
  hiddenClass: string;
  ltsOnlyValue: any;
  latestVersionTarget: HTMLElement;
  linkTarget: HTMLElement;
  urlValue: string;

  connect() {
    this.checkVersion();
  }

  checkVersion() {
    const releasesUrl = this.urlValue;
    const currentVersion = new VersionNumber(this.currentVersionValue);
    const showLTSOnly = this.ltsOnlyValue;
    fetch(releasesUrl, {
      referrerPolicy: 'strict-origin-when-cross-origin',
    })
      .then((response) => {
        if (response.status !== 200) {
          // eslint-disable-next-line no-console
          console.error(
            `Unexpected response from ${releasesUrl}. Status: ${response.status}`,
          );
          return false;
        }
        return response.json();
      })
      .then((payload) => {
        let data = payload;
        if (data && data.lts && showLTSOnly) {
          data = data.lts;
        }

        if (data && data.version) {
          const latestVersion = new VersionNumber(data.version);
          const versionDelta = currentVersion.howMuchBehind(latestVersion);

          let releaseNotesUrl = null;
          if (!versionDelta) {
            return;
          }
          if (
            versionDelta === VersionDeltaType.MAJOR ||
            versionDelta === VersionDeltaType.MINOR
          ) {

Review comment (suggestion):
We could probably use Stimulus' error callbacks here - avoids us calling console.error directly 

Double check but I'm pretty sure you can just throw an error and Stimulus will just handle this Async and push it to logging if needed. It won't break the whole JS UI - just stop the specific controller method from being run. 

```
throw Error('Unexpexted...');
```

See
- https://github.com/hotwired/stimulus/blob/main/src/core/application.ts#L87
- https://stimulus.hotwired.dev/handbook/installing#error-handling


Code after:
 *
 * Expected JSON payload:
 *
 * {
 *     "version": "2.15.2",
 *     "url":     "https://docs.wagtail.io/en/stable/releases/2.15.2.html",
 *     "minorUrl": "https://docs.wagtail.io/en/stable/releases/2.15.html",
 *     "lts": {
 *         "version": "2.12.8",
 *         "url": "https://docs.wagtail.io/en/stable/releases/2.12.8.html",
 *         "minorUrl": "https://docs.wagtail.io/en/stable/releases/2.12.html"
 *     }
 * }
 */
export class UpgradeController extends Controller<HTMLElement> {
  static classes = ['hidden'];
  static targets = ['latestVersion', 'link'];
  static values = {
    currentVersion: String,
    ltsOnly: { default: false, type: Boolean },
    url: { default: 'https://releases.wagtail.org/latest.txt', type: String },
  };

  currentVersionValue: string;
  hiddenClass: string;
  latestVersionTarget: HTMLElement;
  linkTarget: HTMLElement;
  ltsOnlyValue: any;
  urlValue: string;

  connect() {
    this.checkVersion();
  }

  checkVersion() {
    const releasesUrl = this.urlValue;
    const currentVersion = new VersionNumber(this.currentVersionValue);
    const showLTSOnly = this.ltsOnlyValue;
    fetch(releasesUrl, {
      referrerPolicy: 'strict-origin-when-cross-origin',
    })
      .then((response) => {
        if (response.status !== 200) {
          throw Error(
            `Unexpected response from ${releasesUrl}. Status: ${response.status}`,
          );
        }
        return response.json();
      })
      .then((payload) => {
        let data = payload;