All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.co.unclealex.diagnostics.JsonErrorHandler.scala Maven / Gradle / Ivy

The newest version!
package uk.co.unclealex.diagnostics

import java.io.{PrintWriter, StringWriter}
import java.nio.charset.StandardCharsets

import akka.util.CompactByteString
import play.api.http.{ContentTypes, HttpEntity, HttpErrorHandler, Status}
import play.api.libs.json._
import play.api.mvc.{RequestHeader, ResponseHeader, Result}
import play.api.{Environment, Mode}

import scala.concurrent.Future

class JsonErrorHandler(environment: Environment) extends HttpErrorHandler with Status {

  val extractStackTrace: Throwable => Option[Seq[String]] = {
    if (environment.mode == Mode.Prod) {
      _ => None
    }
    else { t: Throwable =>
      val writer = new StringWriter()
      t.printStackTrace(new PrintWriter(writer))
      Some(writer.toString.split('\n'))
    }
  }

  override def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result] = {
    handleError(statusCode, message, None)
  }

  override def onServerError(request: RequestHeader, exception: Throwable): Future[Result] = {
    handleError(INTERNAL_SERVER_ERROR, exception.getMessage, extractStackTrace(exception))
  }

  def handleError(statusCode: Int, message: String, maybeStackTrace: Option[Seq[String]]): Future[Result] = {
    val responseHeader = ResponseHeader(statusCode)
    val error: JsObject = JsObject(Seq(
      "statusCode" -> JsNumber(statusCode),
      "message" -> JsString(message)) ++
      maybeStackTrace.map(stackTrace => "stackTrace" -> JsArray(stackTrace.map(el => JsString(el.trim)))))
    val body = HttpEntity.Strict(
      CompactByteString(Json.stringify(error).getBytes(StandardCharsets.UTF_8)),
      Some(ContentTypes.JSON))
    Future.successful(Result(responseHeader, body))
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy