Permalink
Browse files

error handling much better for missing templates

  • Loading branch information...
malgorithms committed Oct 11, 2012
1 parent fa71faa commit 71a73d43aea0c695b3c4ea85edaf110f5cf418ef
Showing with 121 additions and 68 deletions.
  1. +4 −0 lib/consts.js
  2. +67 −41 lib/engine.js
  3. +1 −0 lib/view.js
  4. +1 −1 package.json
  5. +4 −1 src/consts.coffee
  6. +43 −25 src/engine.coffee
  7. +1 −0 src/view.coffee
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
View
@@ -1,7 +1,7 @@
{
"name": "toffee",
"description": "An Express 3.x and 2.x templating language based on CoffeeScript with slicker tokens and syntax. Built with love at OkCupid.",
- "version": "0.0.45",
+ "version": "0.0.46",
"directories": {
"lib": "./lib"
},
View
@@ -2,4 +2,7 @@ exports.states =
TOFFEE: 1
COFFEE: 2
-exports.TAB_SPACES = 2
+exports.TAB_SPACES = 2
+
+exports.tweakables =
+ MISSING_FILE_RECHECK: 1000 #ms
View
@@ -1,9 +1,9 @@
-{view} = require './view'
-{states} = require './consts'
-utils = require './utils'
-fs = require 'fs'
-path = require 'path'
-util = require 'util'
+{view} = require './view'
+{states, tweakables} = require './consts'
+utils = require './utils'
+fs = require 'fs'
+path = require 'path'
+util = require 'util'
class engine
@@ -12,7 +12,8 @@ class engine
@verbose = options.verbose or false
@minimize = options.minimize or false
@prettyPrintErrors = if options.prettyPrintErrors? then options.prettyPrintErrors else true
- @viewCache = {} # filename
+ @viewCache = {} # filename -> view
+ @fsErrorCache = {} # filename -> timestamp last failed
_log: (o) ->
if @verbose
@@ -117,32 +118,25 @@ class engine
catch e
txt = "Error: Could not read #{filename}"
if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}"
- view_options =
+ @fsErrorCache[filename] = Date.now()
+ view_options =
fileName: filename
verbose: @verbose
prettyPrintErrors: @prettyPrintErrors
minimize: @minimize
- v = new view txt, view_options
+ v = new view txt, view_options
@viewCache[filename] = v
@_monitorForChanges filename, options
v
- _monitorForChanges: (filename, options) ->
- ###
- we must continuously unwatch/rewatch because some editors/systems invoke a "rename"
- event and we'll end up following the wrong, old 'file' as a new one
- is dropped in its place.
- ###
- fsw = null
- fsw = fs.watch filename, {persistent: true}, (change) =>
- fsw.close()
- @_log "Got an fs.watch hit on #{filename}"
- fs.readFile filename, 'utf8', (err, txt) =>
- @_monitorForChanges filename, options
- if txt isnt @viewCache[filename].txt
- if err
- txt = "Error: Could not read #{filename} after fs.watch() hit."
- if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}"
+ _reloadFileInBkg: (filename, options) ->
+ fs.readFile filename, 'utf8', (err, txt) =>
+ if err or (txt isnt @viewCache[filename].txt)
+ if err
+ @fsErrorCache[filename] = Date.now()
+ txt = "Error: Could not read #{filename}"
+ if options.__toffee?.parent? then txt += " requested in #{options.__toffee.parent}"
+ if not (err and @viewCache[filename].fsError) # i.e., don't just create a new error view
view_options =
fileName: filename
verbose: @verbose
@@ -151,6 +145,30 @@ class engine
cb: (v) =>
@_log "#{filename} updated and ready"
@viewCache[filename] = v
+ if err
+ view_options.fsError = true
v = new view txt, view_options
+ _monitorForChanges: (filename, options) ->
+ ###
+ we must continuously unwatch/rewatch because some editors/systems invoke a "rename"
+ event and we'll end up following the wrong, old 'file' as a new one
+ is dropped in its place.
+ ###
+ if @fsErrorCache[filename]? and ((Date.now() - @fsErrorCache[filename]) > tweakables.MISSING_FILE_RECHECK)
+ delete @fsErrorCache[filename]
+ @_reloadFileInBkg filename, options
+ @_monitorForChanges filename, options
+ else
+ fsw = null
+ try
+ @_log "#{filename} starting fs.watch()"
+ fsw = fs.watch filename, {persistent: true}, (change) =>
+ @_log "#{filename} closing fs.watch()"
+ fsw.close()
+ @_monitorForChanges filename, options
+ @_reloadFileInBkg filename, options
+ catch e
+ setTimeout (=> @_monitorForChanges filename, options), tweakables.MISSING_FILE_RECHECK
+
exports.engine = engine
View
@@ -157,6 +157,7 @@ class view
@browserMode = options.browserMode or false
@minimize = options.minimize or false # excludes line numbers from coffee ; uses uglify.JS
@verbose = options.verbose or false
+ @fsError = options.fsError or false # pass true if you could not load the view template and passed in error text
@prettyPrintErrors = if options.prettyPrintErrors? then options.prettyPrintErrors else true
@txt = txt
@tokenObj = null # constructed as needed

0 comments on commit 71a73d4

Please sign in to comment.