1010#include < google/protobuf/message.h>
1111#include < grpcpp/server_context.h>
1212
13+ #include < userver/logging/log.hpp>
1314#include < userver/server/handlers/exceptions.hpp>
1415#include < userver/tracing/in_place_span.hpp>
16+ #include < userver/utils/fast_scope_guard.hpp>
1517#include < userver/utils/impl/internal_tag.hpp>
1618
1719#include < userver/ugrpc/server/exceptions.hpp>
@@ -125,6 +127,9 @@ class CallProcessor final {
125127 RunOnCallStart ();
126128
127129 bool finished = false ;
130+ const utils::FastScopeGuard post_finish_hooks_guard ([this , &finished]() noexcept {
131+ RunOnCallFinish (finished ? std::make_optional (std::move (status_)) : std::nullopt );
132+ });
128133
129134 // Don't keep the config snapshot for too long, especially for streaming RPCs.
130135 state_.config_snapshot .reset ();
@@ -138,7 +143,7 @@ class CallProcessor final {
138143 }
139144
140145 if (!engine::current_task::ShouldCancel () && !responder_.IsInterrupted ()) {
141- RunOnCallFinish (response);
146+ RunPreFinishHooks (response);
142147 finished = impl::Finish (responder_, response, status_);
143148 }
144149
@@ -183,7 +188,7 @@ class CallProcessor final {
183188 }
184189 }
185190
186- void RunOnCallFinish (std::optional<Response>& response) {
191+ void RunPreFinishHooks (std::optional<Response>& response) {
187192 const auto & mids = state_.middlewares ;
188193 const auto rbegin = mids.rbegin () + (mids.size () - success_pre_hooks_count_);
189194 for (auto it = rbegin; it != mids.rend (); ++it) {
@@ -197,8 +202,20 @@ class CallProcessor final {
197202 }
198203 }
199204
200- // We must call all OnRpcFinish despite the failures. So, don't check the status.
201- RunWithCatch ([this , &middleware] { middleware->OnCallFinish (middleware_call_context_, status_); });
205+ RunWithCatch ([this , &middleware] { middleware->PreSendStatus (middleware_call_context_, status_); });
206+ }
207+ }
208+
209+ void RunOnCallFinish (const std::optional<grpc::Status>& status) {
210+ const auto & mids = state_.middlewares ;
211+ const auto rbegin = mids.rbegin () + (mids.size () - success_pre_hooks_count_);
212+ for (auto it = rbegin; it != mids.rend (); ++it) {
213+ const auto & middleware = *it;
214+ try {
215+ middleware->OnCallFinish (middleware_call_context_, status);
216+ } catch (const std::exception& ex) {
217+ LOG_WARNING () << " Error in OnCallFinish: " << ex;
218+ }
202219 }
203220 }
204221
0 commit comments