Skip to content

Commit

Permalink
Merge b73c5db into 75eb080
Browse files Browse the repository at this point in the history
  • Loading branch information
notslang committed Jun 4, 2014
2 parents 75eb080 + b73c5db commit 475c919
Show file tree
Hide file tree
Showing 13 changed files with 162 additions and 84 deletions.
1 change: 1 addition & 0 deletions .npmignore
@@ -1,6 +1,7 @@
test
src
Makefile
assets
contributing.md
.editorconfig
.travis.yml
6 changes: 0 additions & 6 deletions README.md
Expand Up @@ -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
Expand Down
20 changes: 20 additions & 0 deletions 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()]
16 changes: 16 additions & 0 deletions 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
3 changes: 3 additions & 0 deletions assets/img/error-icon.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added assets/js/index.coffee
Empty file.
23 changes: 0 additions & 23 deletions lib/404.html

This file was deleted.

54 changes: 35 additions & 19 deletions 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
38 changes: 23 additions & 15 deletions package.json
@@ -1,34 +1,42 @@
{
"name": "apology-middleware",
"description": "middleware for custom error pages",
"version": "0.0.4",
"author": "Carrot Creative <dev@carrotcreative.com>",
"description": "middleware for custom error pages",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/kylemac/apology-middleware.git"
"dependencies": {
"accepts": "^1.0.2"
},
"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",
"coveralls": "*",
"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": "*"
}
}
26 changes: 26 additions & 0 deletions public/index.html
@@ -0,0 +1,26 @@
<!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...</title></head><body><style>body {
background: #f4f2f0;
font-family: "Helvetica Neue", HelveticaNeue, Helvetica, Arial, sans-serif;
}
svg,
h1 {
margin: 0.8em 2em;
}
h1 {
color: #a49e9a;
font-weight: 300;
text-align: center;
}
svg {
display: block;
margin-left: auto;
margin-right: auto;
}
</style><script>(function() {


}).call(this);
</script><svg width="68" height="68" xmlns="http://www.w3.org/2000/svg">
<path d="M0 34c0 18.785 15.215 34 34 34s34-15.215 34-34-15.215-34-34-34-34 15.215-34 34zm44.572-17l6.428 6.46-10.53 10.625 10.403 10.408-6.47 6.507-10.403-10.459-10.361 10.459-6.47-6.507 10.403-10.408-10.572-10.625 6.47-6.46 10.53 10.574 10.572-10.574z" fill="#C2471B"></path>
</svg>
<h1>Something went wrong : (</h1></body></html>
40 changes: 19 additions & 21 deletions 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()
Expand All @@ -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) ->
Expand All @@ -49,15 +48,14 @@ describe 'custom with absolute path', ->
res.text.should.equal("<p>custom</p>\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("<p>custom</p>\n")
done()
10 changes: 10 additions & 0 deletions 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 : (
9 changes: 9 additions & 0 deletions 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

0 comments on commit 475c919

Please sign in to comment.