Skip to content

Commit 91e56b7

Browse files
committed
Move the try blocks to call stack management
1 parent 4baba48 commit 91e56b7

File tree

5 files changed

+142
-191
lines changed

5 files changed

+142
-191
lines changed

app/_meta.global.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { Heart } from "lucide-react";
44
const DOCS_ITEMS: MetaRecord = {
55
index: '',
66
navigation: '',
7-
tips: '',
87
}
98

109
export default {

content/docs/API/_meta.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
export default {
22
'call_stack_management': '',
3-
'error_propagation': '',
3+
'throwing_errors': '',
44
'error_types': '',
55
'inline_logging': '',
66
'signal_handling': '',

content/docs/API/call_stack_management.mdx

Lines changed: 135 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ void TRACE(expr)
2525
Always use `TRY` instead of `TRACE` when error handling matters.
2626
It is easy to miss errors as `TRACE` are not checking for errors stored
2727
in context.
28-
[See `TRY`](/docs/API/error_propagation#try-)
28+
[See `TRY`](/docs/API/call_stack_management#try-)
2929
</Callout>
3030
3131
#### Parameters
@@ -69,7 +69,7 @@ void TRACE_BLOCK(...)
6969
Always call `ctb_check_error` after `TRACE_BLOCK` when error handling matters.
7070
It is easy to miss errors as `TRACE_BLOCK` are not checking for errors stored
7171
in context.
72-
[See `ctb_check_error`](/docs/API/error_propagation#ctb_check_error-)
72+
[See `ctb_check_error`](/docs/API/throwing_errors#ctb_check_error-)
7373
</Callout>
7474

7575
#### Parameters
@@ -102,4 +102,137 @@ int function_a(void)
102102
// Note: i is not accessible here
103103
// printf("%d", i); <-- Illegal!
104104
}
105+
```
106+
107+
### `TRY` <Badge text="Macro" />
108+
Wrapper macro for expression to automatically manage call stack frames and check for errors.
109+
```c
110+
bool TRY(expr)
111+
```
112+
113+
#### Parameters
114+
<ParamsTable
115+
params={[
116+
{ name: "expr", type: "N/A", desc: "The expression to be traced." },
117+
]}
118+
/>
119+
120+
#### Returns
121+
<ParamsTable
122+
params={[
123+
{ name: "success", type: "bool", desc: "Whether the expression executed without error." },
124+
]}
125+
/>
126+
127+
#### Expands to
128+
```c
129+
(ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #expr), \
130+
(expr), \
131+
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #expr), \
132+
!ctb_check_error())
133+
```
134+
135+
#### Usage
136+
```c
137+
int function_a(void)
138+
{
139+
bool success = TRY(function_b()); // Try a function call
140+
}
141+
142+
int function_b(void)
143+
{
144+
int i = 0;
145+
(void) TRY(i = 2); // Try any expression
146+
}
147+
```
148+
149+
### `TRY_GOTO` <Badge text="Macro" />
150+
Wrapper for an expression. If an error occurs after the expression, jump to label.
151+
```c
152+
void TRY_GOTO(expr, label)
153+
```
154+
155+
#### Parameters
156+
<ParamsTable
157+
params={[
158+
{ name: "expr", type: "N/A", desc: "The expression to be traced." },
159+
{ name: "label", type: "N/A", desc: "The label to jump to on error." },
160+
]}
161+
/>
162+
163+
#### Expands to
164+
```c
165+
do \
166+
{ \
167+
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #expr); \
168+
(expr); \
169+
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #expr); \
170+
if (ctb_check_error()) \
171+
{ \
172+
goto label; \
173+
} \
174+
} while (0)
175+
```
176+
177+
#### Usage
178+
```c
179+
int function_a(void)
180+
{
181+
TRY_GOTO(function_b(), error); // Trace a function call
182+
/* Do something */
183+
184+
return 0;
185+
186+
error:
187+
return 1;
188+
}
189+
```
190+
191+
### `TRY_BLOCK_GOTO` <Badge text="Macro" />
192+
Wrapper for a block of code. If an error occurs after the block executes, jump to label.
193+
```c
194+
void TRY_BLOCK_GOTO(label, ...)
195+
```
196+
197+
#### Parameters
198+
<ParamsTable
199+
params={[
200+
{ name: "label", type: "N/A", desc: "The label to jump to on error." },
201+
{ name: "...", type: "N/A", desc: "The block of code to be traced." },
202+
]}
203+
/>
204+
205+
#### Expands to
206+
```c
207+
do \
208+
{ \
209+
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__); \
210+
__VA_ARGS__ \
211+
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__); \
212+
if (ctb_check_error()) \
213+
{ \
214+
goto label; \
215+
} \
216+
} while (0)
217+
```
218+
219+
#### Usage
220+
```c
221+
int function_a(void)
222+
{
223+
/* Trace a code block */
224+
TRY_BLOCK_GOTO(
225+
error,
226+
int *ptr;
227+
printf("%d", *ptr); // Oops, segmentation fault
228+
); // <-- Don't forget the semi-colon
229+
230+
// Note: i is not accessible here
231+
// printf("%d", i); <-- Illegal!
232+
233+
return 0;
234+
235+
error:
236+
return 1;
237+
}
105238
```
Lines changed: 6 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
---
2-
title: Error Propagation
2+
title: Error Generation
33
---
44

55
import ParamsTable from "components/params-table.tsx";
66

7-
# Error propagation
7+
# Throwing Errors and Logging
88

9-
With the call stack infrastructure in place, the next challenge
10-
is to effectively propagate error states up the stack. Since C lacks
11-
built-in exception handling, we have to direct the control
12-
flow ourselves when an error occurs. To streamline this process and ensure
13-
tracebacks are preserved, we provide a set of tools below.
14-
15-
<Callout type="warning">Do not use jump statements inside macro, including `break`, `continue`, `return` and `goto`.</Callout>
9+
While [Call Stack Management](/docs/API/call_stack_management) handles the execution flow and context,
10+
we need specific tools to originate and visualize errors. This
11+
section provides the tools to throw errors, checking the error states,
12+
and dumping traceback when error occurs.
1613

1714
## API
1815

@@ -58,11 +55,6 @@ Wrapper for raising an error with formatted message with the current call stack.
5855
```c
5956
void THROW_FMT(CTB_Error ctb_error, const char *restrict msg, ...);
6057
```
61-
62-
<Callout type="info">
63-
Pass `""` to `msg` when error message is not needed.
64-
</Callout>
65-
6658
<Callout type="warning">
6759
`THROW_FMT` simply records the error. It has no
6860
effect if you forget to do error checking.
@@ -130,139 +122,6 @@ error:
130122
────────────────────────────────────────────────────────────────────────────────
131123
```
132124

133-
### `TRY` <Badge text="Macro" />
134-
Wrapper macro for expression to automatically manage call stack frames and check for errors.
135-
```c
136-
bool TRY(expr)
137-
```
138-
139-
#### Parameters
140-
<ParamsTable
141-
params={[
142-
{ name: "expr", type: "N/A", desc: "The expression to be traced." },
143-
]}
144-
/>
145-
146-
#### Returns
147-
<ParamsTable
148-
params={[
149-
{ name: "success", type: "bool", desc: "Whether the expression executed without error." },
150-
]}
151-
/>
152-
153-
#### Expands to
154-
```c
155-
(ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #expr), \
156-
(expr), \
157-
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #expr), \
158-
!ctb_check_error())
159-
```
160-
161-
#### Usage
162-
```c
163-
int function_a(void)
164-
{
165-
bool success = TRY(function_b()); // Try a function call
166-
}
167-
168-
int function_b(void)
169-
{
170-
int i = 0;
171-
(void) TRY(i = 2); // Try any expression
172-
}
173-
```
174-
175-
### `TRY_GOTO` <Badge text="Macro" />
176-
Wrapper for an expression. If an error occurs after the expression, jump to label.
177-
```c
178-
void TRY_GOTO(expr, label)
179-
```
180-
181-
#### Parameters
182-
<ParamsTable
183-
params={[
184-
{ name: "expr", type: "N/A", desc: "The expression to be traced." },
185-
{ name: "label", type: "N/A", desc: "The label to jump to on error." },
186-
]}
187-
/>
188-
189-
#### Expands to
190-
```c
191-
do \
192-
{ \
193-
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #expr); \
194-
(expr); \
195-
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #expr); \
196-
if (ctb_check_error()) \
197-
{ \
198-
goto label; \
199-
} \
200-
} while (0)
201-
```
202-
203-
#### Usage
204-
```c
205-
int function_a(void)
206-
{
207-
TRY_GOTO(function_b(), error); // Trace a function call
208-
/* Do something */
209-
210-
return 0;
211-
212-
error:
213-
return 1;
214-
}
215-
```
216-
217-
### `TRY_BLOCK_GOTO` <Badge text="Macro" />
218-
Wrapper for a block of code. If an error occurs after the block executes, jump to label.
219-
```c
220-
void TRY_BLOCK_GOTO(label, ...)
221-
```
222-
223-
#### Parameters
224-
<ParamsTable
225-
params={[
226-
{ name: "label", type: "N/A", desc: "The label to jump to on error." },
227-
{ name: "...", type: "N/A", desc: "The block of code to be traced." },
228-
]}
229-
/>
230-
231-
#### Expands to
232-
```c
233-
do \
234-
{ \
235-
ctb_push_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__); \
236-
__VA_ARGS__ \
237-
ctb_pop_call_stack_frame(__FILE__, __func__, __LINE__, #__VA_ARGS__); \
238-
if (ctb_check_error()) \
239-
{ \
240-
goto label; \
241-
} \
242-
} while (0)
243-
```
244-
245-
#### Usage
246-
```c
247-
int function_a(void)
248-
{
249-
/* Trace a code block */
250-
TRY_BLOCK_GOTO(
251-
error,
252-
int *ptr;
253-
printf("%d", *ptr); // Oops, segmentation fault
254-
); // <-- Don't forget the semi-colon
255-
256-
// Note: i is not accessible here
257-
// printf("%d", i); <-- Illegal!
258-
259-
return 0;
260-
261-
error:
262-
return 1;
263-
}
264-
```
265-
266125
### `ctb_check_error` <Badge text="Function" />
267126
Check if any error has occurred.
268127
```c

content/docs/tips.mdx

Lines changed: 0 additions & 40 deletions
This file was deleted.

0 commit comments

Comments
 (0)