Не могу понять как при 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}/`);
}