0
# Flow Control Exceptions
1
2
Exception handling for when parameter flow control is triggered. `ParamFlowException` provides detailed information about which parameter caused the flow control, enabling precise error handling and monitoring in applications.
3
4
## Capabilities
5
6
### Basic Exception Creation
7
8
Creates parameter flow exceptions with resource and parameter information.
9
10
```java { .api }
11
/**
12
* Create parameter flow exception with resource name and parameter value
13
* @param resourceName the resource that triggered flow control
14
* @param param the parameter value that caused the trigger
15
*/
16
public ParamFlowException(String resourceName, String param);
17
18
/**
19
* Create parameter flow exception with resource, parameter, and rule information
20
* @param resourceName the resource that triggered flow control
21
* @param param the parameter value that caused the trigger
22
* @param rule the rule that was triggered
23
*/
24
public ParamFlowException(String resourceName, String param, ParamFlowRule rule);
25
26
/**
27
* Create parameter flow exception with message and cause
28
* @param resourceName the resource name
29
* @param message the exception message
30
* @param cause the underlying cause
31
*/
32
public ParamFlowException(String resourceName, String message, Throwable cause);
33
```
34
35
**Usage Example:**
36
37
```java
38
// Exceptions are typically thrown by Sentinel automatically
39
try {
40
Entry entry = SphU.entry("userService", EntryType.IN, 1, "VIP_USER");
41
// ... business logic
42
} catch (ParamFlowException ex) {
43
// Handle parameter flow control exception
44
System.out.println("Resource: " + ex.getResourceName());
45
System.out.println("Parameter: " + ex.getLimitParam());
46
System.out.println("Rule: " + ex.getRule());
47
}
48
```
49
50
### Resource Information
51
52
Provides information about the resource that triggered the parameter flow control.
53
54
```java { .api }
55
/**
56
* Get the resource name that triggered the parameter flow control
57
* @return resource name
58
*/
59
public String getResourceName();
60
```
61
62
**Usage Example:**
63
64
```java
65
try {
66
processUserRequest("high_frequency_user");
67
} catch (ParamFlowException ex) {
68
String resource = ex.getResourceName();
69
70
// Log with resource context
71
logger.warn("Parameter flow control triggered for resource: {}", resource);
72
73
// Resource-specific handling
74
if ("userService".equals(resource)) {
75
handleUserServiceFlowControl(ex);
76
} else if ("productService".equals(resource)) {
77
handleProductServiceFlowControl(ex);
78
}
79
}
80
```
81
82
### Parameter Information
83
84
Provides the specific parameter value that caused the flow control to trigger.
85
86
```java { .api }
87
/**
88
* Get the parameter value that triggered the parameter flow control
89
* @return the parameter value
90
*/
91
public String getLimitParam();
92
```
93
94
**Usage Example:**
95
96
```java
97
try {
98
processUserData(userId, productId);
99
} catch (ParamFlowException ex) {
100
String limitParam = ex.getLimitParam();
101
102
// Log the specific parameter that caused the issue
103
logger.warn("Flow control triggered by parameter: {}", limitParam);
104
105
// Parameter-specific handling
106
if (limitParam.startsWith("VIP_")) {
107
// Handle VIP user flow control
108
notifyVipSupport(limitParam);
109
} else if (limitParam.matches("\\d+")) {
110
// Handle numeric parameter (e.g., product ID)
111
handleProductFlowControl(limitParam);
112
}
113
}
114
```
115
116
### Rule Information
117
118
Provides access to the specific rule that was triggered.
119
120
```java { .api }
121
/**
122
* Get triggered rule.
123
* Note: the rule result is a reference to rule map and SHOULD NOT be modified.
124
* @return triggered rule
125
*/
126
public ParamFlowRule getRule();
127
```
128
129
**Usage Example:**
130
131
```java
132
try {
133
performOperation(userId);
134
} catch (ParamFlowException ex) {
135
ParamFlowRule rule = ex.getRule();
136
137
if (rule != null) {
138
// Access rule details for better error handling
139
int paramIdx = rule.getParamIdx();
140
double count = rule.getCount();
141
int grade = rule.getGrade();
142
143
logger.warn("Parameter flow control: resource={}, param={}, " +
144
"paramIdx={}, count={}, grade={}",
145
ex.getResourceName(), ex.getLimitParam(),
146
paramIdx, count, grade);
147
148
// Rule-specific handling
149
if (rule.getGrade() == RuleConstant.FLOW_GRADE_QPS) {
150
handleQpsFlowControl(ex, rule);
151
} else if (rule.getGrade() == RuleConstant.FLOW_GRADE_THREAD) {
152
handleThreadFlowControl(ex, rule);
153
}
154
}
155
}
156
```
157
158
## Exception Handling Patterns
159
160
### Basic Exception Handling
161
162
```java
163
import com.alibaba.csp.sentinel.SphU;
164
import com.alibaba.csp.sentinel.Entry;
165
import com.alibaba.csp.sentinel.EntryType;
166
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
167
168
public void processUserRequest(String userId) {
169
Entry entry = null;
170
try {
171
entry = SphU.entry("userService", EntryType.IN, 1, userId);
172
173
// Your business logic here
174
performUserOperation(userId);
175
176
} catch (ParamFlowException ex) {
177
// Handle parameter flow control
178
logger.warn("User {} hit flow control limit", ex.getLimitParam());
179
throw new ServiceException("Service temporarily unavailable for user: " + userId);
180
181
} catch (BlockException ex) {
182
// Handle other types of flow control
183
logger.warn("General flow control triggered for resource: {}", ex.getResourceName());
184
throw new ServiceException("Service temporarily unavailable");
185
186
} finally {
187
if (entry != null) {
188
entry.exit();
189
}
190
}
191
}
192
```
193
194
### Advanced Exception Handling with Metrics
195
196
```java
197
private final Counter paramFlowControlCounter = Counter.build()
198
.name("param_flow_control_total")
199
.help("Parameter flow control triggered count")
200
.labelNames("resource", "parameter")
201
.register();
202
203
public void processWithMetrics(String resourceName, Object... params) {
204
Entry entry = null;
205
try {
206
entry = SphU.entry(resourceName, EntryType.IN, 1, params);
207
208
// Business logic
209
doBusinessLogic(params);
210
211
} catch (ParamFlowException ex) {
212
// Record metrics
213
paramFlowControlCounter.labels(ex.getResourceName(), ex.getLimitParam()).inc();
214
215
// Detailed logging
216
ParamFlowRule rule = ex.getRule();
217
if (rule != null) {
218
logger.warn("Parameter flow control triggered: " +
219
"resource={}, parameter={}, limit={}, grade={}",
220
ex.getResourceName(), ex.getLimitParam(),
221
rule.getCount(), rule.getGrade());
222
}
223
224
// Business-specific handling
225
handleParameterFlowControl(ex);
226
227
} finally {
228
if (entry != null) {
229
entry.exit();
230
}
231
}
232
}
233
234
private void handleParameterFlowControl(ParamFlowException ex) {
235
String param = ex.getLimitParam();
236
String resource = ex.getResourceName();
237
238
// Notify monitoring systems
239
alertingService.sendAlert("Parameter flow control",
240
"Resource: " + resource + ", Parameter: " + param);
241
242
// Implement fallback logic
243
if ("userService".equals(resource)) {
244
// Redirect to fallback user service
245
fallbackUserService.processUser(param);
246
}
247
}
248
```
249
250
### Exception Handling with Retry Logic
251
252
```java
253
import java.util.concurrent.TimeUnit;
254
255
public void processWithRetry(String userId, int maxRetries) {
256
int attempts = 0;
257
258
while (attempts < maxRetries) {
259
Entry entry = null;
260
try {
261
entry = SphU.entry("userService", EntryType.IN, 1, userId);
262
263
// Business logic
264
performUserOperation(userId);
265
return; // Success, exit retry loop
266
267
} catch (ParamFlowException ex) {
268
attempts++;
269
270
logger.warn("Parameter flow control attempt {}/{}: user={}, rule={}",
271
attempts, maxRetries, ex.getLimitParam(),
272
ex.getRule() != null ? ex.getRule().getCount() : "unknown");
273
274
if (attempts >= maxRetries) {
275
// Max retries reached
276
logger.error("Max retries reached for user: {}", userId);
277
throw new ServiceException("Service unavailable after retries", ex);
278
}
279
280
// Wait before retry with exponential backoff
281
try {
282
TimeUnit.MILLISECONDS.sleep(100 * attempts);
283
} catch (InterruptedException e) {
284
Thread.currentThread().interrupt();
285
throw new ServiceException("Interrupted during retry", e);
286
}
287
288
} finally {
289
if (entry != null) {
290
entry.exit();
291
}
292
}
293
}
294
}
295
```
296
297
## Exception Properties
298
299
`ParamFlowException` extends `BlockException` and has the following characteristics:
300
301
- **Stack trace**: Overrides `fillInStackTrace()` to return `this` for performance
302
- **Resource name**: Always available through `getResourceName()`
303
- **Parameter value**: Available through `getLimitParam()` (alias for `getMessage()`)
304
- **Rule reference**: Available through `getRule()` when exception includes rule information
305
- **Thread safety**: Immutable once created, safe for concurrent access
306
307
## Best Practices
308
309
1. **Always handle in finally blocks**: Use try-finally to ensure `entry.exit()` is called
310
2. **Log parameter information**: Include both resource and parameter in logs for debugging
311
3. **Implement fallback logic**: Provide alternative processing paths when flow control triggers
312
4. **Monitor exception patterns**: Track which parameters frequently trigger flow control
313
5. **Don't modify rule references**: The rule returned by `getRule()` should not be modified