diff --git a/handlers/errorHandlers.js b/handlers/errorHandlers.js index 48465e4..9fc3ce0 100644 --- a/handlers/errorHandlers.js +++ b/handlers/errorHandlers.js @@ -7,6 +7,8 @@ exports.catchErrors = (fn) => { return function (req, res, next) { - return fn(req, res, next).catch(next) + return fn(req, res, next).catch((e) => { + next(e) + }) } } diff --git a/routes/courses.js b/routes/courses.js index 6552e6b..bf77d18 100644 --- a/routes/courses.js +++ b/routes/courses.js @@ -36,14 +36,13 @@ router.get('/:slug', catchErrors(async function (req, res, next) { const lessonIndex = lessons.findIndex((lesson) => lesson.fields.slug === req.params.lslug) const lesson = lessons[lessonIndex] const cookie = req.cookies.visitedLessons - let visitedLessons = cookie || [] + let visitedLessons = cookie || [] visitedLessons.push(course.sys.id) visitedLessons = [...new Set(visitedLessons)] res.cookie('visitedLessons', visitedLessons, { maxAge: 900000, httpOnly: true }) res.render('course', {title: course.fields.title, course, lesson, lessons, lessonIndex, visitedLessons}) })) - /* GET course lesson detail. */ router.get('/:cslug/lessons/:lslug', catchErrors(async function (req, res, next) { let course = await getCourse(req.params.cslug, req.query.locale, req.query.api) diff --git a/services/contentful.js b/services/contentful.js index 312573c..e176eea 100644 --- a/services/contentful.js +++ b/services/contentful.js @@ -23,13 +23,13 @@ exports.initClient = (options) => { }) } -exports.getCourses = (locale = 'en-US', api = `cda`) => { +exports.getCourses = assert((locale = 'en-US', api = `cda`) => { // to get all the courses we request all the entries // with the content_type `course` from Contentful const client = api === 'cda' ? cdaClient : cpaClient return client.getEntries({content_type: 'course', locale, include: 10}) .then((response) => response.items) -} +}, 'Course') exports.getLandingPage = (locale = 'en-US', api = `cda`) => { // our Home page is fully configureable via Contentful @@ -39,26 +39,22 @@ exports.getLandingPage = (locale = 'en-US', api = `cda`) => { .then((response) => response.items[0]) } -exports.getCourse = (slug, locale = 'en-US', api = `cda`) => { +exports.getCourse = assert((slug, locale = 'en-US', api = `cda`) => { // the SDK supports link resolution only when you call the collection endpoints // That's why we are using getEntries with a query instead of getEntry(entryId) // make sure to specify the content_type whenever you want to perform a query const client = api === 'cda' ? cdaClient : cpaClient return client.getEntries({content_type: 'course', 'fields.slug': slug, locale, include: 10}) .then((response) => response.items[0]) -} +}, 'Course') -exports.getLessons = (courseId, locale = 'en-US', api = `cda`) => { - // TODO -} - -exports.getCategories = (locale = 'en-US', api = `cda`) => { +exports.getCategories = assert((locale = 'en-US', api = `cda`) => { const client = api === 'cda' ? cdaClient : cpaClient return client.getEntries({content_type: 'category', locale}) .then((response) => response.items) -} +}, 'Course') -exports.getCoursesByCategory = (category, locale = 'en-US', api = `cda`) => { +exports.getCoursesByCategory = assert((category, locale = 'en-US', api = `cda`) => { const client = api === 'cda' ? cdaClient : cpaClient return client.getEntries({ content_type: 'course', @@ -67,5 +63,18 @@ exports.getCoursesByCategory = (category, locale = 'en-US', api = `cda`) => { include: 10 }) .then((response) => response.items) -} +}, 'Category') +function assert (fn, context) { + return function (req, res, next) { + return fn(req, res, next) + .then((data) => { + if (!data) { + var err = new Error(`${context} Not Found`) + err.status = 404 + throw err + } + return data + }) + } +} diff --git a/views/error.pug b/views/error.pug index 1c6e394..cceb8e7 100644 --- a/views/error.pug +++ b/views/error.pug @@ -2,6 +2,15 @@ extends layout block content .layout-centered - h1= message - h2= error.status - pre #{error.stack} + .error + h1 Oops Something went wrong (#{error.status}) + h2 Try: + ul + li Check if the content model has changed + li Check the selection has content in draft or published state (for Preview or Delivery) + li Check if there's any content for this locale + li Verify credentials are correct and up to date + li Check the stack trace below + + h2 Stack trace + pre.error__stack-trace #{error.stack}