在 Ember / Ember 数据应用程序中捕获(失败)net::ERR_NAME_NOT_RESOLVED

Catch (failed)net::ERR_NAME_NOT_RESOLVED in an Ember / Ember Data app

我正在开发一个使用 Ember 数据的 Ember 应用程序。我们主要使用 Rails 和 Postgres 作为后端,但我们的一小部分数据存储在 WordPress 后端。 WordPress 在 wp.example.com 上 运行。

Ember 数据设置为与 Rails 和 WordPress 后端一起使用,所以我可以这样做:

// Get WordPress category by slug
this.store.query('wordpress/category', { slug }).then((models) => {
  // Leave page if no category was found
  if (typeof models.get('firstObject') == 'undefined') this.transitionTo('backupRoute');

  return models.get('firstObject');
});

现在我想知道如果 wp 子域离线,我如何捕获错误。

当我更改 WordPress 后端 URL(我不确定这是否是模拟故障的最佳方式)时,我在 Chrome DevTools 中得到 (failed)net::ERR_NAME_NOT_RESOLVED 几次后秒和 Ember 显示错误 500。相反,我想捕获网络错误并做一些有用的事情,在这种情况下,重定向。

有没有办法捕获这些错误?添加一个简单的 catch() 会完全破坏页面。当有待处理的请求时,它会保持白色约两分钟,然后显示 502 Bad Gateway。我也在日志中得到这个:

my_service_1 | (node:1) UnhandledPromiseRejectionWarning: [object Object]
my_service_1 | (node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 13)

这个问题在今天的 May I Ask a Question 节目中有提到。

这些代码示例来自 Octane 风格的应用程序并具有 Octane 语法,但这些功能在旧 Ember 版本中也可用。

一些内置的 Ember 功能将在此处帮助您:Loading and Error Substates 和错误事件。

首先,你需要抛出错误。然后你需要添加一个错误动作并说出错误发生时应该发生什么。当您的请求出错时,错误事件会自动触发,您可以将转换代码放在那里。错误事件处理是 Ember 路由的一个特性。

import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';

export default class ArticlesOverviewRoute extends Route {
  @service store;

  model(params) {
    return this.store.query('wordpress/category', { slug }).then((models) => {
      if (typeof models.get('firstObject') == 'undefined') {
        throw new Error("Sorry, there was a problem")
      };
    });
  }

  @action
  error(error, transition) {
    this.transitionTo('backupRoute')
  }
};

或者,如果您的目标是显示错误页面,您可以做一些更简单的事情。使用此命令创建错误模板:ember g template error。这将创建一个模板文件 app/templates/error.hbs。在模板中添加一些文本,例如“oops!”,这样您就可以在它运行时看到它。

您仍然需要抛出错误以便 Ember 可以注意到它,但您不再需要错误操作。 Ember 将自动路由到错误模板。

export default class ArticlesOverviewRoute extends Route {
  @service store;

  model(params) {
    return this.store.query('wordpress/category', { slug }).then((models) => {
      if (typeof models.get('firstObject') == 'undefined') {
        throw new Error("Sorry, there was a problem")
      };
    });
  }
};

错误模板可以存在于许多不同的路由中。指南包含所有详细信息,但一般来说,您可以将它们放在您的路线文件夹中,例如 some-route/error.hbs 或者您可以将它们放在应用程序的根目录中,就像我们对 ember g template error[=18 所做的那样=]