Alenorze
@Alenorze
Не люблю Индию

Koa.js как ловить 404 и перенаправлять на 404 страницу?

Не могу понять как при 404 перенаправлять на 404 страницу, выбивает Not Found, версия koa 1.1.2

#!/usr/bin/env node
"use strict";

// todo: trailing slash hard check

const CATALOGS = [
  {name: 'Межкомнатные двери',  slug: 'room',       url: '/catalog/room/'},
  {name: 'Металлические двери', slug: 'metal',      url: '/catalog/metal/'},
  {name: 'Фурнитура',           slug: 'furniture',  url: '/catalog/furniture/'},
  {name: 'Полы',                slug: 'floor',      url: '/catalog/floor/'}
];
const CATALOG_ROOM_ID = 0;
const CATALOG_METAL_ID = 1;
const CATALOG_FURNITURE_ID = 2;
const CATALOG_FLOOR_ID = 3;
const CATALOGS_MAP = {
  room: CATALOG_ROOM_ID,
  metal: CATALOG_METAL_ID,
  furniture: CATALOG_FURNITURE_ID,
  floor: CATALOG_FLOOR_ID
};

const conf = require('./conf');

// ********************************************************* END OF CONSTS DEF

var views = require('co-views');
var knex = require('koa-knex');
var markdown = require('markdown-it')();
var coBody = require('co-body');
var app = module.exports = require('koa')();
var catalog = require('./app/catalog');

if (conf.app.serveStatic) {
  let statik = require('koa-static');
  let mount = require('koa-mount');
  app.use(statik(conf.nginx.staticDir));
  app.use(mount('/media', statik(conf.mediaRoot)));
}

app.use(knex(conf.knexConnection));

app.use(function* callback(next) {
  if (this.path != '/callback/') {
    return yield next;
  }

  // todo
  //if (this.method != 'POST') {
  //  this.status = 405;
  //  this.set('Allowed', 'POST');
  //  return yield next;
  //}

  var params = yield coBody.form(this);
  var phone = params.phone;

  console.log(this.body);

  var query = this.knex
    .insert({phone: phone})
    .into('shop_callback');
  var result = yield query;
  //console.log(result);

  this.body = 'ok';
});

app.use(function* mainMiddleware(next) {
  this.locals = {};
  this.locals.markdown = markdown;
  this.locals.catalogs = CATALOGS;
  this.locals.url = this.url;
  this.locals.path = this.request.path;
  this.locals.templateDebug = conf.app.templateDebug;
  this.locals.showYandexMetrika = conf.app.showYandexMetrika;
  this.locals.menu = yield catalog.catalogMenu(this.knex, CATALOGS);
  //this.knex.on('query', console.log);
  this.locals.seo = (yield this.knex
    .select('meta_description', 'meta_keywords')
    .from('seo_uri')
    .where('uri', this.request.path))[0];
  this.template = null;
  yield next;
  if (this.template) {
    var render = views(__dirname + '/tpl', {default: 'jade'});
    this.body = yield render(this.template, this.locals);
  }
});

app.use(function* catalogCommon(next) {
  if (!~this.url.indexOf('/catalog/')) {
    return yield next;
  }

  this.assert(!~this.path.indexOf('//'), 404);
  var parts = this.path.split('/').filter(val => val);

  if (parts[2]) {
    if (parts[2][0] == '_') {
      // special type of flatpage requested - go to flatpages
      return yield next;
    } else if (parts[2][0] == '-') {
      this.locals.groupPart = parts[2].slice(1);
    } else {
      this.locals.sectionPart = parts[2];
    }
  }

  this.locals.catalogPart = parts[1];
  if (!this.locals.catalogPart) {
    return yield next;
  }

  this.locals.productPart = parts[3];
  this.assert(!parts[4], 404);

  this.locals.catalogId = CATALOGS_MAP[this.locals.catalogPart];
  this.assert(this.locals.catalogId !== undefined, 404);
  this.locals.catalog = CATALOGS[this.locals.catalogId];

  // current section search
  if (this.locals.sectionPart) {
    this.locals.menu[this.locals.catalogId].sections.forEach(section => {
      if (section.slug == this.locals.sectionPart) {
        this.locals.section = section;
      }
    });
    this.assert(this.locals.section, 404);
  }

  // current group search
  if (this.locals.groupPart) {
    this.locals.menu[this.locals.catalogId].groups.forEach(group => {
      if (group.slug == this.locals.groupPart) {
        this.locals.group = group;
      }
    });
    this.assert(this.locals.group, 404);
  }

  // request for flatpages, what must appear in this catalog globally
  this.locals.flatpages = yield this.knex
    .select('title', 'url')
    .from('flatpage')
    .whereRaw(`url ~* '^/catalog/${this.locals.catalogPart}/_'`)
    .orderBy('title');

  yield next;
});

app.use(function* catalogProduct(next) {
  if (!this.locals.productPart) {
    return yield next;
  }
  this.locals.product = yield catalog[this.locals.catalogPart + 'Product'](this.knex, this.locals.section.id, this.locals.productPart);
  this.assert(this.locals.product, 404);
  this.locals.options = yield catalog[this.locals.catalogPart + 'ProductOptions'](this.knex, this.locals.product.id);

  this.locals.extraImgs = yield this.knex
    .select('img')
    .from(`catalog_${this.locals.catalogPart}_productextraimg`)
    .where('system_id', this.locals.product.id)
    .orderBy('order');

  if (this.locals.catalogPart == 'room') {
    this.locals.related = yield catalog.relatedFurniture(this.knex);
    this.locals.relatedCatalog = CATALOGS[2];
  } else {
    this.locals.related = yield catalog.relatedRoom(this.knex);
    this.locals.relatedCatalog = CATALOGS[0];
  }

  this.template = 'catalog_product';
});

app.use(function* catalogList(next) {
  if (!this.locals.catalogPart) {
    return yield next;
  }
  var klass = catalog[this.locals.catalogPart + 'List'];
  var list = new klass(this.knex,
                       this.locals.section && this.locals.section.id,
                       this.request.query,
                       this.locals.group && this.locals.group.id);
  yield* list.process();

  this.locals.priceRange = list.priceRange;
  this.locals.priceRangeSelected = list.priceRangeSelected;
  this.locals.brandsForm = list.brandsForm;
  this.locals.sizesForm = list.sizesForm;
  this.locals.colorGroupsForm = list.colorGroupsForm;
  this.locals.items = list.products;

  this.template = 'catalog_list';
});

app.use(function* salons(next) {
  if (this.path != '/salons/') {
    return yield next;
  }
  this.template = 'salons';
});

app.use(function* flatpage() {
  var query = this.knex
    .select('url', 'title', 'content')
    .from('flatpage')
    .where('url', this.url);

  this.locals.page = (yield query)[0];
  this.assert(this.locals.page, 404);

  if (this.url == '/') {
    this.template = 'home';
    this.locals.banners = yield this.knex
      .select('img')
      .from('banner')
      .orderBy('order');
  } else {
    this.template = 'flatpage';
  }
});


if (!module.parent) {
  app.listen(conf.app.port, conf.app.host);
  console.log(`listening on http://${conf.app.host}:${conf.app.port}/`);
}
  • Вопрос задан
  • 394 просмотра
Решения вопроса 1
edli007
@edli007
full stack, team lead
вот же говнокодище.......

Последними юзом делаете 404, пройдя через все роуты и ненайдя соответсвий он дойдет до послледнего и сделает 404

Или сделайте последний роутер страничку ошибок, а предпоследний роутер генератор 404 как это создает стандартный CLI от express.

Второй способ типовое решение.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы