He-Pin opened a new issue, #3265:
URL: https://github.com/apache/pekko/issues/3265
### Motivation
When an actor mixing in `Timers` throws while handling a **timer-triggered**
message, the internal `TimerSchedulerImpl.TimerMsg` wrapper leaks into the
supervision machinery (`preRestart` / the failed-message reported to the
supervisor) instead of the unwrapped user message that `receive` actually
processed. This only happens for actors that are **not** stash-capable.
### Current Behavior
`Timers.aroundReceive` unwraps the `TimerMsg` and invokes the user's
`receive`
with the unwrapped message `m`, but it only rewrites
`ActorCell.currentMessage`
to that unwrapped message when the actor is a `StashSupport`:
`actor/src/main/scala/org/apache/pekko/actor/Timers.scala:53-67`:
```scala
case timerMsg: TimerSchedulerImpl.TimerMsg =>
_timers.interceptTimerMsg(timerMsg) match {
case OptionVal.Some(m: AutoReceivedMessage) => ...
case OptionVal.Some(m) =>
if (this.isInstanceOf[StashSupport]) {
actorCell.currentMessage = actorCell.currentMessage.copy(message = m)
}
super.aroundReceive(receive, m)
case _ => // discard
}
```
For a **non-stash** actor the `currentMessage` rewrite is skipped, so
`currentMessage.message` remains the internal `TimerMsg` wrapper.
`ActorCell.invoke` sets `currentMessage = messageHandle` and, on failure,
routes
to `handleInvokeFailure`, which reports `currentMessage` to the supervisor
and
passes `currentMessage.message` to `preRestart(reason, message)`
(`actor/src/main/scala/org/apache/pekko/actor/ActorCell.scala:552-560`). As a
result, `preRestart` and the supervisor strategy observe a
`TimerSchedulerImpl.TimerMsg` (an internal type) rather than the message the
user's `receive` was actually given.
### Expected Behavior
The failed message surfaced to `preRestart` and to the supervisor for a
timer-triggered failure should be the **unwrapped** user message, consistent
with what `receive` processed — for all actors, not only stash-capable ones.
### Suggested Fix
Rewrite `currentMessage` to the unwrapped message unconditionally (not only
for
`StashSupport` actors) before delegating to `super.aroundReceive`, so that
both
stash and supervision observe the unwrapped message. This is a superset of
the
stash-specific rewrite that already exists.
### Notes
- Typed actors are not affected: timer messages are unwrapped before the
behavior is interpreted.
- This was noticed while reviewing the stash-side variant of the same root
cause (the `StashSupport` guard).
### Environment
- Pekko Actor (any version)
- `Timers.scala:53-67`, `ActorCell.scala:552-560`
### References
None
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]