When replacing one output with another, we were calling suspend
on the old output's observer object. This prevents the observer
from being scheduled in the future, but it doesn't prevent an
already-scheduled execution from proceeding. Since we have a new
definition for what an output is, there's no way another execution
of the old observer will do anything useful.
One simple way to see the difference this commit makes is to
create a simple Shiny app that sets output$plot twice in server.R,
with a println in each renderPlot. You'll see that both execute
once, whereas with this change only the most recently set renderPlot
gets executed.
No known errors will occur when printing the stack trace, but since
this is fairly complicated code executing when an error has already
happened, better to be on the defensive.
It is dangerous to set this on a per-process basis. If we even
still want the ability to have observer errors not kill the
session (debatable) we should do so by having an option on the
session object that is set when the shiny server function runs.
Not only does this remove support for the option, but now we
will refuse to connect and will abort the session if the option
is set to a non-NULL value. This is to prevent apps from moving
forward with the assumption that their option will work, when
it really won't. (I doubt anyone is using it anyway, it's so
obscure...)
- More selective removal of frames at end of call stack
- Add withLogErrors, printError, stripStackTrace convenience funcs
- Properly capture/log errors for various levels of unhandled errors
- Unhide stacks for flush/flushed/sessionended callbacks
The session$makeScope function was not correctly taking the session's
own namespace into account (i.e. all makeScope() method calls were
being performed against the root session).
These functions were created before getDefaultReactiveDomain()
existed, so the only way to get ahold of the current session was
if the caller explicitly passed it.
This is slightly backwards incompatible, in that existing calls
to invalidateLater() that don't pass a session argument will
behave slightly differently (bound to the current session instead
of to no session), but those calls would have triggered a warning
for all but the very earliest versions of Shiny.
Commit 07f2792cf9 introduced an error, replacing `e$parent = parentSession` with `e$parent <= parentSession`, while it should have been `e$parent <- parentSession`