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}/`);
}
  • Вопрос задан
  • 397 просмотров
Решения вопроса 1
edli007
@edli007
full stack, team lead
вот же говнокодище.......

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

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

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

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

Похожие вопросы