From c001ede6963e22878d1886fe9a658052c8087af1 Mon Sep 17 00:00:00 2001 From: Sean Lang Date: Thu, 29 May 2014 15:39:09 -0500 Subject: [PATCH 1/5] update repo url --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0eac7c7..9a16a48 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "MIT", "repository": { "type": "git", - "url": "https://github.com/kylemac/apology-middleware.git" + "url": "https://github.com/carrot/apology-middleware.git" }, "main": "lib", "devDependencies": { From 2096e4193bf9e29159fc6fc9bbf70175b41d2272 Mon Sep 17 00:00:00 2001 From: Sean Lang Date: Tue, 3 Jun 2014 14:38:38 -0500 Subject: [PATCH 2/5] rewrite using roots and supporting non-404 errors also allow errors to be sent as JSON, HTML and plain text depending on the accepts header --- app.coffee | 20 +++++++++++++++ assets/css/index.styl | 16 ++++++++++++ assets/img/error-icon.svg | 3 +++ assets/js/index.coffee | 0 lib/404.html | 23 ----------------- lib/index.coffee | 54 +++++++++++++++++++++++++-------------- package.json | 38 ++++++++++++++++----------- public/index.html | 26 +++++++++++++++++++ test/test.coffee | 40 ++++++++++++++--------------- views/index.jade | 10 ++++++++ views/layout.jade | 9 +++++++ 11 files changed, 161 insertions(+), 78 deletions(-) create mode 100644 app.coffee create mode 100644 assets/css/index.styl create mode 100644 assets/img/error-icon.svg create mode 100644 assets/js/index.coffee delete mode 100644 lib/404.html create mode 100644 public/index.html create mode 100644 views/index.jade create mode 100644 views/layout.jade diff --git a/app.coffee b/app.coffee new file mode 100644 index 0000000..c33af55 --- /dev/null +++ b/app.coffee @@ -0,0 +1,20 @@ +axis = require 'axis' +rupture = require 'rupture' +autoprefixer = require 'autoprefixer-stylus' + +module.exports = + ignores: [ + '**/layout.*' + '**/_*' + '.gitignore' + 'lib/**' + 'assets/**' + 'test/**' + '*.md' # specific to this project + '.editorconfig' + '.npmignore' + '.travis.yml' + 'Makefile' + ] + stylus: + use: [axis(), rupture(), autoprefixer()] diff --git a/assets/css/index.styl b/assets/css/index.styl new file mode 100644 index 0000000..d0ee4ee --- /dev/null +++ b/assets/css/index.styl @@ -0,0 +1,16 @@ +body + background #F4F2F0 + font-family "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif + +svg, h1 + margin .8em 2em + +h1 + color #A49E9A + font-weight 300 + text-align center + +svg + display block + margin-left auto + margin-right auto diff --git a/assets/img/error-icon.svg b/assets/img/error-icon.svg new file mode 100644 index 0000000..4d0aedb --- /dev/null +++ b/assets/img/error-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/js/index.coffee b/assets/js/index.coffee new file mode 100644 index 0000000..e69de29 diff --git a/lib/404.html b/lib/404.html deleted file mode 100644 index 4eaac0d..0000000 --- a/lib/404.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - Uh oh... - - - -
- -

Something went wrong : (

-
- - diff --git a/lib/index.coffee b/lib/index.coffee index 05ad6e2..6f93c2d 100644 --- a/lib/index.coffee +++ b/lib/index.coffee @@ -1,30 +1,46 @@ fs = require 'fs' path = require 'path' +accepts = require 'accepts' ###* * Configures options and returns a middleware function. - * - * @param {String} file - path to custom error page. Default 'lib/404.html' + * @param {String} [file='public/index.html'] - path to custom error page. * @return {Function} middleware function ### - -module.exports = (root, file) -> - fallback = path.join(__dirname, '404.html') - error_page = fallback - - if not file and root - error_page = path.resolve(root) - - if file and root - error_page = path.join(root, file) +module.exports = (file = path.join(__dirname, '/../public/index.html')) -> + if arguments.length > 1 + # support passing `root` as first arg for backwards compatibility. remove + # this later + file = path.join(arguments...) return (err, req, res, next) -> - res.statusCode = 404 - res.setHeader('Content-Type', 'text/html') + res.statusCode = ( + if err.status + err.status + else if res.statusCode < 400 + 500 + ) + accept = accepts(req) - if not fs.lstatSync(error_page).isDirectory() - res.write(fs.readFileSync(error_page)) - else - res.write(fs.readFileSync(fallback)) + if accept.type('html') + fs.readFile file, 'utf8', (err, html) -> + if err + res.statusCode = 500 + next(err) + else + res.setHeader 'Content-Type', 'text/html; charset=utf-8' + res.end html + else if accept.type('json') + error = + message: err.message + stack: err.stack - res.end() + for prop of err + continue + json = JSON.stringify(error: error) + res.setHeader 'Content-Type', 'application/json' + res.end json + else + # send plain text + res.setHeader 'Content-Type', 'text/plain' + res.end err.stack diff --git a/package.json b/package.json index 9a16a48..24aa3c0 100644 --- a/package.json +++ b/package.json @@ -1,34 +1,42 @@ { "name": "apology-middleware", + "description": "middleware for custom error pages", "version": "0.0.4", "author": "Carrot Creative ", - "description": "middleware for custom error pages", - "license": "MIT", - "repository": { - "type": "git", - "url": "https://github.com/carrot/apology-middleware.git" + "dependencies": { + "accepts": "^1.0.2", + "coveralls": "*" }, - "main": "lib", "devDependencies": { - "mocha": "*", + "alchemist-middleware": "0.0.4", + "autoprefixer-stylus": "0.1.x", + "axis": "0.2.x", "chai": "*", "chai-http": "*", + "coffee-script": "1.7.x", "coffeelint": "*", + "connect": "2.15.x", "istanbul": "*", + "jade": "1.x", + "marked": "0.3.x", + "mocha": "*", "mocha-lcov-reporter": "*", - "coffee-script": "1.7.x", - "connect": "2.15.x" + "rupture": "0.1.x", + "stylus": "0.45.x" + }, + "engines": { + "node": ">=0.10.0" + }, + "license": "MIT", + "main": "lib", + "repository": { + "type": "git", + "url": "https://github.com/carrot/apology-middleware.git" }, "scripts": { "test": "npm run lint && mocha", "lint": "find lib/ -name '*.coffee' | xargs coffeelint", "coverage": "make build; istanbul cover _mocha --report html -- -R spec && open coverage/index.html && make unbuild", "coveralls": "make build; istanbul cover _mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage; make unbuild" - }, - "engines": { - "node": ">=0.10.0" - }, - "dependencies": { - "coveralls": "*" } } diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..f50afa9 --- /dev/null +++ b/public/index.html @@ -0,0 +1,26 @@ +Uh oh... + + +

Something went wrong : (

\ No newline at end of file diff --git a/test/test.coffee b/test/test.coffee index 6133dab..9783be4 100644 --- a/test/test.coffee +++ b/test/test.coffee @@ -1,13 +1,11 @@ connect = require 'connect' -path = require 'path' -fs = require 'fs' +path = require 'path' +fs = require 'fs' +alchemist = require 'alchemist-middleware' describe 'basic', -> - before -> - @app = connect() - .use((req, res, next)-> next('forced error')) - .use(apology()) + @app = connect().use(alchemist('./')).use(apology()) it 'should be registered as middleware', -> (-> connect().use(apology())).should.not.throw() @@ -16,30 +14,31 @@ describe 'basic', -> chai.request(@app).get('/not-found.html').res (res) -> res.should.have.status(404) res.should.be.html - base = fs.readFileSync(path.join(__dirname, '..', 'lib', '404.html'), 'utf8') + base = fs.readFileSync( + path.join(__dirname, '../public/index.html') + 'utf8' + ) res.text.should.equal(base) done() -describe 'custom with only root path', -> - +describe 'custom with relative path', -> before -> @app = connect() - .use((req, res, next)-> next('forced error')) - .use(apology(base_path)) + .use(alchemist('./')) + .use(apology('not-found.html')) - it 'should return default 404 when only root path is passed', (done) -> + it 'should return 500 when passed error page is missing', (done) -> chai.request(@app).get('/not-found.html').res (res) -> - res.should.have.status(404) + res.should.have.status(500) res.should.be.html - base = fs.readFileSync(path.join(__dirname, '..', 'lib', '404.html'), 'utf8') - res.text.should.equal(base) + res.text.should.equal("Error: ENOENT, open 'not-found.html'\n\n") done() describe 'custom with absolute path', -> before -> custom = path.join(base_path, 'custom.html') @app = connect() - .use((req, res, next)-> next('forced error')) + .use(alchemist('./')) .use(apology(custom)) it 'should return custom 404', (done) -> @@ -49,15 +48,14 @@ describe 'custom with absolute path', -> res.text.should.equal("

custom

\n") done() -describe 'custom with root path and file', -> +describe 'forced error', -> before -> @app = connect() .use((req, res, next)-> next('forced error')) - .use(apology(base_path, 'custom.html')) + .use(apology()) - it 'should return custom 404', (done) -> + it 'should return 500', (done) -> chai.request(@app).get('/not-found.html').res (res) -> - res.should.have.status(404) + res.should.have.status(500) res.should.be.html - res.text.should.equal("

custom

\n") done() diff --git a/views/index.jade b/views/index.jade new file mode 100644 index 0000000..472a964 --- /dev/null +++ b/views/index.jade @@ -0,0 +1,10 @@ +extends layout + +block content + style + include:stylus ../assets/css/index.styl + script + include:coffee ../assets/js/index.coffee + + include ../assets/img/error-icon.svg + h1 Something went wrong : ( diff --git a/views/layout.jade b/views/layout.jade new file mode 100644 index 0000000..d51fd6d --- /dev/null +++ b/views/layout.jade @@ -0,0 +1,9 @@ +doctype html +html + head + meta(charset='utf8') + meta(http-equiv='X-UA-Compatible', content='IE=edge, chrome=1') + meta(name='viewport', content='width=device-width') + title Uh oh... + body + block content From 6af2f300534d53c74f8e373e943076f54876f97d Mon Sep 17 00:00:00 2001 From: Sean Lang Date: Tue, 3 Jun 2014 14:46:34 -0500 Subject: [PATCH 3/5] deprecate multiple args one is all you need --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index b6b325b..816d027 100644 --- a/README.md +++ b/README.md @@ -34,12 +34,6 @@ var app = connect() var server = http.createServer(app).listen(1111) ``` -Apology can optionally take two arguments, a `root` and a `file`. These two will automatically be joined. - -```js -apology(__dirname, 'custom.html'); -``` - If you don't specify a custom error page then apology will serve our standard error file for you (don't worry, it's quite handsome). ### License & Contributing From 7c15068fc4e275604a2106e52386e14a173900fd Mon Sep 17 00:00:00 2001 From: Sean Lang Date: Tue, 3 Jun 2014 15:05:32 -0500 Subject: [PATCH 4/5] move coveralls from deps to devDeps --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 24aa3c0..c9492b4 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,7 @@ "version": "0.0.4", "author": "Carrot Creative ", "dependencies": { - "accepts": "^1.0.2", - "coveralls": "*" + "accepts": "^1.0.2" }, "devDependencies": { "alchemist-middleware": "0.0.4", @@ -16,6 +15,7 @@ "coffee-script": "1.7.x", "coffeelint": "*", "connect": "2.15.x", + "coveralls": "*", "istanbul": "*", "jade": "1.x", "marked": "0.3.x", From b73c5db7d4bb55747e114106ecbe0ea18e3a4dad Mon Sep 17 00:00:00 2001 From: Sean Lang Date: Wed, 4 Jun 2014 09:59:42 -0500 Subject: [PATCH 5/5] ignore ./assets when deploying to npm everything is compiled into ./public, so those aren't needed --- .npmignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.npmignore b/.npmignore index 71f7e16..7c6c95e 100644 --- a/.npmignore +++ b/.npmignore @@ -1,6 +1,7 @@ test src Makefile +assets contributing.md .editorconfig .travis.yml