package iris_test import ( "gopkg.in/kataras/iris.v6" "gopkg.in/kataras/iris.v6/httptest" "testing" ) func TestTransaction(t *testing.T) { app := iris.New() app.Adapt(newTestNativeRouter()) firstTransactionFailureMessage := "Error: Virtual failure!!!" secondTransactionSuccessHTMLMessage := "

This will sent at all cases because it lives on different transaction and it doesn't fails

" persistMessage := "

I persist show this message to the client!

" maybeFailureTransaction := func(shouldFail bool, isRequestScoped bool) func(t *iris.Transaction) { return func(t *iris.Transaction) { // OPTIONAl, the next transactions and the flow will not be skipped if this transaction fails if isRequestScoped { t.SetScope(iris.RequestTransactionScope) } // OPTIONAL STEP: // create a new custom type of error here to keep track of the status code and reason message err := iris.NewTransactionErrResult() t.Context.Text(iris.StatusOK, "Blablabla this should not be sent to the client because we will fill the err with a message and status") fail := shouldFail if fail { err.StatusCode = iris.StatusInternalServerError err.Reason = firstTransactionFailureMessage } // OPTIONAl STEP: // but useful if we want to post back an error message to the client if the transaction failed. // if the reason is empty then the transaction completed successfully, // otherwise we rollback the whole response body and cookies and everything lives inside the transaction.Request. t.Complete(err) } } successTransaction := func(scope *iris.Transaction) { if scope.Context.Request.RequestURI == "/failAllBecauseOfRequestScopeAndFailure" { t.Fatalf("We are inside successTransaction but the previous REQUEST SCOPED TRANSACTION HAS FAILED SO THiS SHOULD NOT BE RAN AT ALL") } scope.Context.HTML(iris.StatusOK, secondTransactionSuccessHTMLMessage) // * if we don't have any 'throw error' logic then no need of scope.Complete() } persistMessageHandler := func(ctx *iris.Context) { // OPTIONAL, depends on the usage: // at any case, what ever happens inside the context's transactions send this to the client ctx.HTML(iris.StatusOK, persistMessage) } app.Get("/failFirsTransactionButSuccessSecondWithPersistMessage", func(ctx *iris.Context) { ctx.BeginTransaction(maybeFailureTransaction(true, false)) ctx.BeginTransaction(successTransaction) persistMessageHandler(ctx) }) app.Get("/failFirsTransactionButSuccessSecond", func(ctx *iris.Context) { ctx.BeginTransaction(maybeFailureTransaction(true, false)) ctx.BeginTransaction(successTransaction) }) app.Get("/failAllBecauseOfRequestScopeAndFailure", func(ctx *iris.Context) { ctx.BeginTransaction(maybeFailureTransaction(true, true)) ctx.BeginTransaction(successTransaction) }) customErrorTemplateText := "

custom error

" app.OnError(iris.StatusInternalServerError, func(ctx *iris.Context) { ctx.Text(iris.StatusInternalServerError, customErrorTemplateText) }) failureWithRegisteredErrorHandler := func(ctx *iris.Context) { ctx.BeginTransaction(func(transaction *iris.Transaction) { transaction.SetScope(iris.RequestTransactionScope) err := iris.NewTransactionErrResult() err.StatusCode = iris.StatusInternalServerError // set only the status code in order to execute the registered template transaction.Complete(err) }) ctx.Text(iris.StatusOK, "this will not be sent to the client because first is requested scope and it's failed") } app.Get("/failAllBecauseFirstTransactionFailedWithRegisteredErrorTemplate", failureWithRegisteredErrorHandler) e := httptest.New(app, t) e.GET("/failFirsTransactionButSuccessSecondWithPersistMessage"). Expect(). Status(iris.StatusOK). ContentType("text/html", app.Config.Charset). Body(). Equal(secondTransactionSuccessHTMLMessage + persistMessage) e.GET("/failFirsTransactionButSuccessSecond"). Expect(). Status(iris.StatusOK). ContentType("text/html", app.Config.Charset). Body(). Equal(secondTransactionSuccessHTMLMessage) e.GET("/failAllBecauseOfRequestScopeAndFailure"). Expect(). Status(iris.StatusInternalServerError). Body(). Equal(firstTransactionFailureMessage) e.GET("/failAllBecauseFirstTransactionFailedWithRegisteredErrorTemplate"). Expect(). Status(iris.StatusInternalServerError). Body(). Equal(customErrorTemplateText) }