userver: userver/error_injection/hook.hpp Source File
Loading...
Searching...
No Matches
hook.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/error_injection/hook.hpp
4/// @brief @copybrief error_injection::Hook
5
6#include <userver/engine/deadline.hpp>
7#include <userver/engine/sleep.hpp>
8#include <userver/error_injection/settings.hpp>
9#include <userver/logging/log.hpp>
10#include <userver/tracing/span.hpp>
11
12USERVER_NAMESPACE_BEGIN
13
14/// Artificial errors injection framework
15namespace error_injection {
16
17/// @brief Single-operation error injection: call PreHook(), run work, then PostHook()
18class Hook final {
19public:
20 explicit Hook(const Settings& settings, engine::Deadline deadline);
21
22 /// Must be called just before actual operation. May sleep for some time,
23 /// throw an exception, or do nothing.
24 /// @throws TimeoutException in case of artificial timeout
25 /// @throws ErrorException in case of artificial error
26 template <typename TimeoutException, typename ErrorException>
27 void PreHook() {
28 if (verdict_ == Verdict::kSkip) {
29 // fast path
30 return;
31 }
32
33 switch (verdict_) {
34 case Verdict::kError:
35 LOG_ERROR() << "Error injection hook triggered verdict: error";
36 throw ErrorException{"error injection"};
37
39 LOG_ERROR() << "Error injection hook triggered verdict: timeout";
40 {
41 auto scope_time = tracing::Span::CurrentSpan().CreateScopeTime("error_injection_timeout");
42 engine::InterruptibleSleepUntil(deadline_);
43 }
44 throw TimeoutException{"error injection"};
45
48 case Verdict::kSkip:
49 // pass
50 ;
51 }
52 }
53
54 /// Must be called just after operation. May sleep for some time,
55 /// or do nothing.
56 void PostHook() {
57 if (verdict_ == Verdict::kSkip) {
58 // fast path
59 return;
60 }
61
62 const engine::Deadline deadline = CalcPostHookDeadline();
63 if (deadline.IsReached()) {
64 return;
65 }
66
67 LOG_ERROR() << "Error injection hook triggered verdict: max-delay / random-delay";
68 auto scope_time = tracing::Span::CurrentSpan().CreateScopeTime("error_injection_delay");
69 engine::InterruptibleSleepUntil(deadline);
70 }
71
72private:
73 engine::Deadline CalcPostHookDeadline();
74
75 static Verdict ReturnVerdict(const Settings& settings);
76
77 const Verdict verdict_;
78 const engine::Deadline deadline_;
79};
80
81} // namespace error_injection
82
83USERVER_NAMESPACE_END