diff options
Diffstat (limited to 'cask')
-rw-r--r-- | cask/src/cask/endpoints/WebSocketEndpoint.scala | 9 | ||||
-rw-r--r-- | cask/src/cask/internal/BatchActor.scala | 7 | ||||
-rw-r--r-- | cask/src/cask/main/Main.scala | 16 | ||||
-rw-r--r-- | cask/src/cask/main/Routes.scala | 5 | ||||
-rw-r--r-- | cask/src/cask/package.scala | 6 | ||||
-rw-r--r-- | cask/src/cask/util/Logger.scala | 18 |
6 files changed, 46 insertions, 15 deletions
diff --git a/cask/src/cask/endpoints/WebSocketEndpoint.scala b/cask/src/cask/endpoints/WebSocketEndpoint.scala index 6728581..a836321 100644 --- a/cask/src/cask/endpoints/WebSocketEndpoint.scala +++ b/cask/src/cask/endpoints/WebSocketEndpoint.scala @@ -4,6 +4,7 @@ import java.nio.ByteBuffer import cask.internal.{BatchActor, Router} import cask.model.Request +import cask.util.Logger import io.undertow.websockets.WebSocketConnectionCallback import io.undertow.websockets.core.{AbstractReceiveListener, BufferedBinaryMessage, BufferedTextMessage, CloseMessage, WebSocketChannel, WebSockets} import io.undertow.websockets.spi.WebSocketHttpExchange @@ -31,7 +32,8 @@ class websocket(val path: String, override val subpath: Boolean = false) def wrapPathSegment(s: String): Seq[String] = Seq(s) } -case class WsHandler(f: WsChannelActor => BatchActor[WsActor.Event])(implicit ec: ExecutionContext) +case class WsHandler(f: WsChannelActor => BatchActor[WsActor.Event]) + (implicit ec: ExecutionContext, log: Logger) extends WebsocketResult with WebSocketConnectionCallback { def onConnect(exchange: WebSocketHttpExchange, channel: WebSocketChannel): Unit = { val actor = f(new WsChannelActor(channel)) @@ -67,7 +69,8 @@ extends WebsocketResult with WebSocketConnectionCallback { } } -class WsChannelActor(channel: WebSocketChannel)(implicit ec: ExecutionContext) +class WsChannelActor(channel: WebSocketChannel) + (implicit ec: ExecutionContext, log: Logger) extends BatchActor[WsActor.Event]{ def run(items: Seq[WsActor.Event]): Unit = items.foreach{ case WsActor.Text(value) => WebSockets.sendTextBlocking(value, channel) @@ -79,7 +82,7 @@ extends BatchActor[WsActor.Event]{ } case class WsActor(handle: PartialFunction[WsActor.Event, Unit]) - (implicit ec: ExecutionContext) + (implicit ec: ExecutionContext, log: Logger) extends BatchActor[WsActor.Event]{ def run(items: Seq[WsActor.Event]): Unit = { items.foreach(handle.applyOrElse(_, (x: WsActor.Event) => ())) diff --git a/cask/src/cask/internal/BatchActor.scala b/cask/src/cask/internal/BatchActor.scala index 1566a18..60b5f57 100644 --- a/cask/src/cask/internal/BatchActor.scala +++ b/cask/src/cask/internal/BatchActor.scala @@ -1,5 +1,7 @@ package cask.internal +import cask.util.Logger + import scala.collection.mutable import scala.concurrent.ExecutionContext @@ -8,7 +10,8 @@ import scala.concurrent.ExecutionContext * of queued items. `run` handles items in batches, to allow for batch * processing optimizations to be used where relevant. */ -abstract class BatchActor[T]()(implicit ec: ExecutionContext) { +abstract class BatchActor[T]()(implicit ec: ExecutionContext, + log: Logger) { def run(items: Seq[T]): Unit private val queue = new mutable.Queue[T]() @@ -24,7 +27,7 @@ abstract class BatchActor[T]()(implicit ec: ExecutionContext) { def runWithItems(): Unit = { val items = synchronized(queue.dequeueAll(_ => true)) try run(items) - catch{case e: Throwable => e.printStackTrace()} + catch{case e: Throwable => log.exception(e)} synchronized{ if (queue.nonEmpty) ec.execute(() => runWithItems()) else{ diff --git a/cask/src/cask/main/Main.scala b/cask/src/cask/main/Main.scala index a5b4dc4..94f7f41 100644 --- a/cask/src/cask/main/Main.scala +++ b/cask/src/cask/main/Main.scala @@ -13,7 +13,7 @@ import io.undertow.util.HttpString * A combination of [[cask.Main]] and [[cask.Routes]], ideal for small * one-file web applications. */ -class MainRoutes extends BaseMain with Routes{ +class MainRoutes extends Main with Routes{ def allRoutes = Seq(this) } @@ -24,16 +24,13 @@ class MainRoutes extends BaseMain with Routes{ * serve, and override various properties on [[Main]] in order to configure * application-wide properties. */ -class Main(servers0: Routes*) extends BaseMain{ - def allRoutes = servers0.toSeq -} -abstract class BaseMain{ +abstract class Main{ def mainDecorators = Seq.empty[cask.main.RawDecorator] def allRoutes: Seq[Routes] def port: Int = 8080 def host: String = "localhost" def debugMode: Boolean = true - + implicit def log = new cask.util.Logger.Console() lazy val routeList = for{ routes <- allRoutes route <- routes.caskMetadata.value.map(x => x: EndpointMetadata[_]) @@ -126,11 +123,16 @@ abstract class BaseMain{ routes: Routes, metadata: EndpointMetadata[_], e: Router.Result.Error) = { + e match { + case e: Router.Result.Error.Exception => log.exception(e.t) + case _ => // do nothing + } val statusCode = e match { case _: Router.Result.Error.Exception => 500 case _: Router.Result.Error.InvalidArguments => 400 case _: Router.Result.Error.MismatchedArguments => 400 } + val str = if (!debugMode) s"Error $statusCode: ${Status.codesToStatus(statusCode).reason}" else ErrorMsgs.formatInvokeError( @@ -138,7 +140,7 @@ abstract class BaseMain{ metadata.entryPoint.asInstanceOf[EntryPoint[cask.main.Routes, _]], e ) - println(str) + Response(str, statusCode = statusCode) } diff --git a/cask/src/cask/main/Routes.scala b/cask/src/cask/main/Routes.scala index be33581..9be9f50 100644 --- a/cask/src/cask/main/Routes.scala +++ b/cask/src/cask/main/Routes.scala @@ -1,9 +1,7 @@ package cask.main - import language.experimental.macros - trait Routes{ def decorators = Seq.empty[cask.main.RawDecorator] @@ -15,5 +13,6 @@ trait Routes{ protected[this] def initialize()(implicit routes: RoutesEndpointsMetadata[this.type]): Unit = { metadata0 = routes } -} + def log: cask.util.Logger +} diff --git a/cask/src/cask/package.scala b/cask/src/cask/package.scala index f72e14b..93c1161 100644 --- a/cask/src/cask/package.scala +++ b/cask/src/cask/package.scala @@ -1,3 +1,5 @@ +import cask.util.Logger + package object cask { // model type Response[T] = model.Response[T] @@ -45,4 +47,8 @@ package object cask { type WsActor = cask.endpoints.WsActor val WsActor = cask.endpoints.WsActor type WsChannelActor = cask.endpoints.WsChannelActor + + // util + type Logger = util.Logger + val Logger = util.Logger } diff --git a/cask/src/cask/util/Logger.scala b/cask/src/cask/util/Logger.scala new file mode 100644 index 0000000..8dc3156 --- /dev/null +++ b/cask/src/cask/util/Logger.scala @@ -0,0 +1,18 @@ +package cask.util + +import sourcecode.{File, Line, Text} + +trait Logger { + def exception(t: Throwable): Unit + + def debug(t: sourcecode.Text[Any])(implicit f: sourcecode.File, line: sourcecode.Line): Unit +} +object Logger{ + class Console() extends Logger{ + def exception(t: Throwable): Unit = t.printStackTrace() + + def debug(t: Text[Any])(implicit f: File, line: Line): Unit = { + println(f.value.split('/').last + ":" + line + " " + t.source + " " + pprint.apply(t.value)) + } + } +}
\ No newline at end of file |