dom96 / jester

A sinatra-like web framework for Nim.
MIT License
1.57k stars 120 forks source link

"error" block of Jester does not work when using custom routers #211

Closed hokamoto closed 2 years ago

hokamoto commented 5 years ago

This issue is from https://forum.nim-lang.org/t/5196

"error" block of Jester does not work when using custom routers. The below code dumps a stack trace instead of the expected message "An exception occurred".

import asyncdispatch, jester, os, strutils, htmlgen

router myrouter:
  get "/":
    raise(newException(OSError, "exception"))

  error Exception:
    resp h1("An exception occurred")

proc main() =
  let port = Port(5000)
  let settings = newSettings(port=port)
  var jester = initJester(myrouter, settings=settings)
  jester.serve()

when isMainModule:
  main()
$ nim -v
Nim Compiler Version 0.20.2 [MacOSX: amd64]
Compiled at 2019-07-18
Copyright (c) 2006-2019 by Andreas Rumpf

active boot switches: -d:release -d:useLinenoise
$ nimble list -i --ver
asynctools  [#pr_fix_compilation]
httpbeast  [0.2.2]
jester  [#head]
capocasa commented 4 years ago

I managed to use this workaround

proc errorHandler(request: Request, error: RouteError): Future[ResponseData] {.async.} =
  block route:
    case error.kind:
      of RouteException:
        let e = getCurrentException()  # error.exc is private
        if e of MyAuthError:
          resp Http401, {"Access-Control-Allow-Origin":"*", "Content-Type":"application/json"}, e.msg
        elif e of ValueError:
          resp Http400, {"Access-Control-Allow-Origin":"*", "Content-Type":"application/json"}, e.msg
        else:
          resp Http500, {"Access-Control-Allow-Origin":"*", "Content-Type":"application/json"}, e.msg
      of RouteCode:
        discard

proc main() =
  let port = Port(5000)
  let settings = newSettings(port=port)
  var jester = initJester(myrouter, settings=settings)
  jester.register(errorHandler)
  jester.serve()

when isMainModule:
  main()
iffy commented 4 years ago

Another workaround that registers the jester-provided error handler:

import asyncdispatch, jester, os, strutils, htmlgen

router myrouter:
  get "/":
    raise(newException(OSError, "exception"))

  error Exception:
    resp h1("An exception occurred")

proc main() =
  let port = Port(5000)
  let settings = newSettings(port=port)
  var jester = initJester(myrouter, settings=settings)
  jester.register(myrouterErrorHandler) # <---- name this ROUTERNAME & "ErrorHandler"
  jester.serve()

when isMainModule:
  main()