Skip to content

Commit

Permalink
Merge pull request #1235 from lift/dpp_issue_1235
Browse files Browse the repository at this point in the history
Transaction S.addAround is broken in some cases
  • Loading branch information
David Pollak committed Mar 12, 2012
2 parents 33bf011 + 380ccf0 commit df9b69d
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 26 deletions.
14 changes: 8 additions & 6 deletions persistence/db/src/main/scala/net/liftweb/db/DB.scala
Expand Up @@ -21,6 +21,8 @@ import common._
import util._ import util._
import Helpers._ import Helpers._


import net.liftweb.http.S

import javax.sql.{DataSource} import javax.sql.{DataSource}
import java.sql.ResultSetMetaData import java.sql.ResultSetMetaData
import java.sql.{Statement, ResultSet, Types, PreparedStatement, Connection, DriverManager} import java.sql.{Statement, ResultSet, Types, PreparedStatement, Connection, DriverManager}
Expand Down Expand Up @@ -240,13 +242,13 @@ trait DB extends Loggable {
try { try {
try { try {
val ret = f val ret = f
success = true success = !S.exceptionThrown_?
ret ret
} catch { } catch {
// this is the case when we want to commit the transaction // this is the case when we want to commit the transaction
// but continue to throw the exception // but continue to throw the exception
case e: LiftFlowOfControlException => { case e: LiftFlowOfControlException => {
success = true success = !S.exceptionThrown_?
throw e throw e
} }
} }
Expand All @@ -263,13 +265,13 @@ trait DB extends Loggable {
try { try {
try { try {
val ret = f val ret = f
success = true success = !S.exceptionThrown_?
ret ret
} catch { } catch {
// this is the case when we want to commit the transaction // this is the case when we want to commit the transaction
// but continue to throw the exception // but continue to throw the exception
case e: LiftFlowOfControlException => { case e: LiftFlowOfControlException => {
success = true success = !S.exceptionThrown_?
throw e throw e
} }
} }
Expand Down Expand Up @@ -676,13 +678,13 @@ trait DB extends Loggable {
var rollback = true var rollback = true
try { try {
val ret = f(conn) val ret = f(conn)
rollback = false rollback = S.exceptionThrown_?
ret ret
} catch { } catch {
// this is the case when we want to commit the transaction // this is the case when we want to commit the transaction
// but continue to throw the exception // but continue to throw the exception
case e: LiftFlowOfControlException => { case e: LiftFlowOfControlException => {
rollback = false rollback = S.exceptionThrown_?
throw e throw e
} }
} finally { } finally {
Expand Down
2 changes: 1 addition & 1 deletion project/Build.scala
Expand Up @@ -109,7 +109,7 @@ object BuildDef extends Build {


lazy val db = lazy val db =
persistenceProject("db") persistenceProject("db")
.dependsOn(util) .dependsOn(util, webkit)
.settings(libraryDependencies += mockito_all) .settings(libraryDependencies += mockito_all)


lazy val proto = lazy val proto =
Expand Down
2 changes: 1 addition & 1 deletion web/webkit/src/main/scala/net/liftweb/http/LiftRules.scala
Expand Up @@ -1299,7 +1299,7 @@ class LiftRules() extends Factory with FormVendor with LazyLoggable {
* a default implementation is already appended. * a default implementation is already appended.
* *
*/ */
@volatile var exceptionHandler = RulesSeq[ExceptionHandlerPF].append { val exceptionHandler = RulesSeq[ExceptionHandlerPF].append {
case (Props.RunModes.Development, r, e) => case (Props.RunModes.Development, r, e) =>
logger.error("Exception being returned to browser when processing " + r.uri.toString + ": " + showException(e)) logger.error("Exception being returned to browser when processing " + r.uri.toString + ": " + showException(e))
XhtmlResponse((<html> <body>Exception occured while processing {r.uri}<pre>{showException(e)}</pre> </body> </html>), S.htmlProperties.docType, List("Content-Type" -> "text/html; charset=utf-8"), Nil, 500, S.ieMode) XhtmlResponse((<html> <body>Exception occured while processing {r.uri}<pre>{showException(e)}</pre> </body> </html>), S.htmlProperties.docType, List("Content-Type" -> "text/html; charset=utf-8"), Nil, 500, S.ieMode)
Expand Down
19 changes: 2 additions & 17 deletions web/webkit/src/main/scala/net/liftweb/http/LiftServlet.scala
Expand Up @@ -294,6 +294,7 @@ class LiftServlet extends Loggable {
case foc: LiftFlowOfControlException => throw foc case foc: LiftFlowOfControlException => throw foc
case e: Exception if !e.getClass.getName.endsWith("RetryRequest") => { case e: Exception if !e.getClass.getName.endsWith("RetryRequest") => {
val bundle = (Props.mode, req, e) val bundle = (Props.mode, req, e)
S.assertExceptionThrown()
NamedPF.applyBox(bundle, LiftRules.exceptionHandler.toList) NamedPF.applyBox(bundle, LiftRules.exceptionHandler.toList)
} }
} }
Expand Down Expand Up @@ -328,7 +329,6 @@ class LiftServlet extends Loggable {
LiftSession.onBeginServicing.foreach(_(liftSession, req)) LiftSession.onBeginServicing.foreach(_(liftSession, req))
val ret: (Boolean, Box[LiftResponse]) = val ret: (Boolean, Box[LiftResponse]) =
try { try {
try {
// run the continuation in the new session // run the continuation in the new session
// if there is a continuation // if there is a continuation
continuation match { continuation match {
Expand All @@ -353,21 +353,6 @@ class LiftServlet extends Loggable {
(true, Full(liftSession.checkRedirect(req.createNotFound(f)))) (true, Full(liftSession.checkRedirect(req.createNotFound(f))))
} }
} }
} catch {
case ContinueResponseException(cre) => throw cre

case ite: java.lang.reflect.InvocationTargetException if (ite.getCause.isInstanceOf[ResponseShortcutException]) =>
(true, Full(liftSession.handleRedirect(ite.getCause.asInstanceOf[ResponseShortcutException], req)))

case rd: net.liftweb.http.ResponseShortcutException => (true, Full(liftSession.handleRedirect(rd, req)))

case e if (e.getClass.getName.endsWith("RetryRequest")) => throw e

case e: LiftFlowOfControlException => throw e

case e => (true, NamedPF.applyBox((Props.mode, req, e), LiftRules.exceptionHandler.toList))

}


} finally { } finally {
if (S.functionMap.size > 0) { if (S.functionMap.size > 0) {
Expand Down Expand Up @@ -489,7 +474,7 @@ class LiftServlet extends Loggable {
} }
} catch { } catch {
case foc: LiftFlowOfControlException => throw foc case foc: LiftFlowOfControlException => throw foc
case e => NamedPF.applyBox((Props.mode, requestState, e), LiftRules.exceptionHandler.toList); case e => S.assertExceptionThrown() ; NamedPF.applyBox((Props.mode, requestState, e), LiftRules.exceptionHandler.toList);
} }
tryo { tryo {
LiftSession.onEndServicing.foreach(_(liftSession, requestState, ret)) LiftSession.onEndServicing.foreach(_(liftSession, requestState, ret))
Expand Down
Expand Up @@ -1145,7 +1145,7 @@ class LiftSession(private[http] val _contextPath: String, val uniqueId: String,


case e: LiftFlowOfControlException => throw e case e: LiftFlowOfControlException => throw e


case e => NamedPF.applyBox((Props.mode, request, e), LiftRules.exceptionHandler.toList); case e => S.assertExceptionThrown() ; NamedPF.applyBox((Props.mode, request, e), LiftRules.exceptionHandler.toList);


} }


Expand Down
14 changes: 14 additions & 0 deletions web/webkit/src/main/scala/net/liftweb/http/S.scala
Expand Up @@ -338,6 +338,8 @@ trait S extends HasParams with Loggable {
private val _oneShot = new ThreadGlobal[Boolean] private val _oneShot = new ThreadGlobal[Boolean]
private val _disableTestFuncNames = new ThreadGlobal[Boolean] private val _disableTestFuncNames = new ThreadGlobal[Boolean]


private object _exceptionThrown extends TransientRequestVar(false)

private object postFuncs extends TransientRequestVar(new ListBuffer[() => Unit]) private object postFuncs extends TransientRequestVar(new ListBuffer[() => Unit])


/** /**
Expand Down Expand Up @@ -386,6 +388,18 @@ trait S extends HasParams with Loggable {


def location: Box[sitemap.Loc[_]] = CurrentLocation.is def location: Box[sitemap.Loc[_]] = CurrentLocation.is



/**
* An exception was thrown during the processing of this request.
* This is tested to see if the transaction should be rolled back
*/
def assertExceptionThrown() {_exceptionThrown.set(true)}

/**
* Was an exception thrown during the processing of the current request?
*/
def exceptionThrown_? : Boolean = _exceptionThrown.get

/** /**
* @return a List of any Cookies that have been set for this Response. If you want * @return a List of any Cookies that have been set for this Response. If you want
* a specific cookie, use findCookie. * a specific cookie, use findCookie.
Expand Down

0 comments on commit df9b69d

Please sign in to comment.