Restart game after unhandled Error?

Hello

I’m using 

Runtime:addEventListener( "unhandledError", handler)

to handle errors and show user message (user can click on it to send email about error).

So my question is: how could I restart game after this?

I tried to show menu scene, but it gives me just a black screen in result.

I added print statements for menu scene and I see that only “create” and “will show” phases was executed - and I have no code for “will show” phase

https://www.tutorialspoint.com/lua/lua_error_handling.htm

I don’t know if there’s a pattern for auto-restarting. Maybe call a dummy function with xpcall watching that starts using composer?

My current code and what I found:
 

local unhandledErrorListener = function( errorEvent ) print("unhandled error listener") composer:removeHidden() local currScene = composer.getSceneName( "current" ) if (currScene ~= nil) then composer.removeScene( currScene ) end composer.gotoScene("UI.errorScene", { params = { error = errorEvent, loadFunction = gameLoaderFunction --this function perform loading last save } }) return true end

So normally I see this situation:
 

X scene show phase = will

X scene show phase = did

ERROR: Runtime error

unhandled error listener

error scene created

error scene show phase = will

error scene show phase = did

remove current (X scene)

But if error occured during another scene show event composer stuck to remove current scene:

X scene show phase = will

X scene show phase = did

ERROR: Runtime error <- this occured right in scene:show event

unhandled error listener

error scene created

error scene show phase = will

remove current (X scene)

So error scene show event never occured with phase = did. And on screen I still see X scene (on which error occured)

The only solution so far for me is to wrap all logic for “did show” phase into timer.performWithDelay

Try and think about this differently… Don’t recycle the scene but instead have a reset() function that restores the scene to it’s default settings.

reset() might work in some cases, but in another situation scene can fail right after create(), so reset wouldn’t help

I just want to show message to the user (show errorScene) and show button to report a crash

If your scene fails to load then you have bigger issues! :wink:

Also never show the user an error screen, silently log the error and deal with it.

So if anyone will stuck with same issue as I: don’t call composer:removeHidden() inside unhandledError listener

To restart the game and all scenes properly I have blankScene, that will execute params.callback on “did show” phase

Restart code: (inside unhandledError listener)

composer.gotoScene("blankScene", { params = { callback = function() composer.removeHidden() timer.performWithDelay(10, function() \_gameLoaderFunction() --this function loads save from file and goes to main scene end) end } })

Blank scene event code:

function scene:show(event) local phase = event.phase if phase == "will" then elseif phase == "did" then if (event.params and event.params.callback) then timer.performWithDelay(10, event.params.callback) end end end

https://www.tutorialspoint.com/lua/lua_error_handling.htm

I don’t know if there’s a pattern for auto-restarting. Maybe call a dummy function with xpcall watching that starts using composer?

My current code and what I found:
 

local unhandledErrorListener = function( errorEvent ) print("unhandled error listener") composer:removeHidden() local currScene = composer.getSceneName( "current" ) if (currScene ~= nil) then composer.removeScene( currScene ) end composer.gotoScene("UI.errorScene", { params = { error = errorEvent, loadFunction = gameLoaderFunction --this function perform loading last save } }) return true end

So normally I see this situation:
 

X scene show phase = will

X scene show phase = did

ERROR: Runtime error

unhandled error listener

error scene created

error scene show phase = will

error scene show phase = did

remove current (X scene)

But if error occured during another scene show event composer stuck to remove current scene:

X scene show phase = will

X scene show phase = did

ERROR: Runtime error <- this occured right in scene:show event

unhandled error listener

error scene created

error scene show phase = will

remove current (X scene)

So error scene show event never occured with phase = did. And on screen I still see X scene (on which error occured)

The only solution so far for me is to wrap all logic for “did show” phase into timer.performWithDelay

Try and think about this differently… Don’t recycle the scene but instead have a reset() function that restores the scene to it’s default settings.

reset() might work in some cases, but in another situation scene can fail right after create(), so reset wouldn’t help

I just want to show message to the user (show errorScene) and show button to report a crash

If your scene fails to load then you have bigger issues! :wink:

Also never show the user an error screen, silently log the error and deal with it.

So if anyone will stuck with same issue as I: don’t call composer:removeHidden() inside unhandledError listener

To restart the game and all scenes properly I have blankScene, that will execute params.callback on “did show” phase

Restart code: (inside unhandledError listener)

composer.gotoScene("blankScene", { params = { callback = function() composer.removeHidden() timer.performWithDelay(10, function() \_gameLoaderFunction() --this function loads save from file and goes to main scene end) end } })

Blank scene event code:

function scene:show(event) local phase = event.phase if phase == "will" then elseif phase == "did" then if (event.params and event.params.callback) then timer.performWithDelay(10, event.params.callback) end end end