Skip to content

Commit 942fe4a

Browse files
authoredMay 28, 2024··
Support returning errors when creating the app (#4565)
The closure passed to `eframe::run_native` now returns a `Result`, allowing you to return an error during app creation, which will be returned to the caller of `run_native`. This means you need to wrap your `Box::new(MyApp::new(…))` in an `Ok(…)`. * Closes #4474
1 parent 54429e0 commit 942fe4a

File tree

28 files changed

+44
-36
lines changed

28 files changed

+44
-36
lines changed
 

‎crates/eframe/src/epi.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,12 @@ pub type EventLoopBuilderHook = Box<dyn FnOnce(&mut EventLoopBuilder<UserEvent>)
4141
#[cfg(any(feature = "glow", feature = "wgpu"))]
4242
pub type WindowBuilderHook = Box<dyn FnOnce(egui::ViewportBuilder) -> egui::ViewportBuilder>;
4343

44+
type DynError = Box<dyn std::error::Error>;
45+
4446
/// This is how your app is created.
4547
///
4648
/// You can use the [`CreationContext`] to setup egui, restore state, setup OpenGL things, etc.
47-
pub type AppCreator = Box<dyn FnOnce(&CreationContext<'_>) -> Box<dyn App>>;
49+
pub type AppCreator = Box<dyn FnOnce(&CreationContext<'_>) -> Result<Box<dyn App>, DynError>>;
4850

4951
/// Data that is passed to [`AppCreator`] that can be used to setup and initialize your app.
5052
pub struct CreationContext<'s> {

‎crates/eframe/src/lib.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//!
3131
//! fn main() {
3232
//! let native_options = eframe::NativeOptions::default();
33-
//! eframe::run_native("My egui App", native_options, Box::new(|cc| Box::new(MyEguiApp::new(cc))));
33+
//! eframe::run_native("My egui App", native_options, Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc)))));
3434
//! }
3535
//!
3636
//! #[derive(Default)]
@@ -90,7 +90,7 @@
9090
//! .start(
9191
//! canvas_id,
9292
//! eframe::WebOptions::default(),
93-
//! Box::new(|cc| Box::new(MyEguiApp::new(cc))),
93+
//! Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc))),)
9494
//! )
9595
//! .await
9696
//! }
@@ -199,7 +199,7 @@ pub mod icon_data;
199199
///
200200
/// fn main() -> eframe::Result<()> {
201201
/// let native_options = eframe::NativeOptions::default();
202-
/// eframe::run_native("MyApp", native_options, Box::new(|cc| Box::new(MyEguiApp::new(cc))))
202+
/// eframe::run_native("MyApp", native_options, Box::new(|cc| Ok(Box::new(MyEguiApp::new(cc)))))
203203
/// }
204204
///
205205
/// #[derive(Default)]
@@ -324,7 +324,7 @@ pub fn run_simple_native(
324324
run_native(
325325
app_name,
326326
native_options,
327-
Box::new(|_cc| Box::new(SimpleApp { update_fun })),
327+
Box::new(|_cc| Ok(Box::new(SimpleApp { update_fun }))),
328328
)
329329
}
330330

@@ -333,6 +333,9 @@ pub fn run_simple_native(
333333
/// The different problems that can occur when trying to run `eframe`.
334334
#[derive(Debug)]
335335
pub enum Error {
336+
/// Something went wrong in user code when creating the app.
337+
AppCreation(Box<dyn std::error::Error>),
338+
336339
/// An error from [`winit`].
337340
#[cfg(not(target_arch = "wasm32"))]
338341
Winit(winit::error::OsError),
@@ -403,6 +406,8 @@ impl From<egui_wgpu::WgpuError> for Error {
403406
impl std::fmt::Display for Error {
404407
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
405408
match self {
409+
Self::AppCreation(err) => write!(f, "app creation error: {err}"),
410+
406411
#[cfg(not(target_arch = "wasm32"))]
407412
Self::Winit(err) => {
408413
write!(f, "winit error: {err}")

‎crates/eframe/src/native/glow_integration.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ impl GlowWinitApp {
313313
raw_window_handle: window.window_handle().map(|h| h.as_raw()),
314314
};
315315
crate::profile_scope!("app_creator");
316-
app_creator(&cc)
316+
app_creator(&cc).map_err(crate::Error::AppCreation)?
317317
};
318318

319319
let glutin = Rc::new(RefCell::new(glutin));

‎crates/eframe/src/native/wgpu_integration.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ impl WgpuWinitApp {
182182
storage: Option<Box<dyn Storage>>,
183183
window: Window,
184184
builder: ViewportBuilder,
185-
) -> Result<&mut WgpuWinitRunning, egui_wgpu::WgpuError> {
185+
) -> crate::Result<&mut WgpuWinitRunning> {
186186
crate::profile_function!();
187187

188188
#[allow(unsafe_code, unused_mut, unused_unsafe)]
@@ -272,7 +272,7 @@ impl WgpuWinitApp {
272272
};
273273
let app = {
274274
crate::profile_scope!("user_app_creator");
275-
app_creator(&cc)
275+
app_creator(&cc).map_err(crate::Error::AppCreation)?
276276
};
277277

278278
let mut viewport_from_window = HashMap::default();

‎crates/eframe/src/web/app_runner.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ impl Drop for AppRunner {
3030

3131
impl AppRunner {
3232
/// # Errors
33-
/// Failure to initialize WebGL renderer.
33+
/// Failure to initialize WebGL renderer, or failure to create app.
3434
pub async fn new(
3535
canvas_id: &str,
3636
web_options: crate::WebOptions,
@@ -71,7 +71,7 @@ impl AppRunner {
7171
let theme = system_theme.unwrap_or(web_options.default_theme);
7272
egui_ctx.set_visuals(theme.egui_visuals());
7373

74-
let app = app_creator(&epi::CreationContext {
74+
let cc = epi::CreationContext {
7575
egui_ctx: egui_ctx.clone(),
7676
integration_info: info.clone(),
7777
storage: Some(&storage),
@@ -86,7 +86,8 @@ impl AppRunner {
8686
wgpu_render_state: painter.render_state(),
8787
#[cfg(all(feature = "wgpu", feature = "glow"))]
8888
wgpu_render_state: None,
89-
});
89+
};
90+
let app = app_creator(&cc).map_err(|err| err.to_string())?;
9091

9192
let frame = epi::Frame {
9293
info,

‎crates/eframe/src/web/web_runner.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ impl WebRunner {
5454
/// Create the application, install callbacks, and start running the app.
5555
///
5656
/// # Errors
57-
/// Failing to initialize graphics.
57+
/// Failing to initialize graphics, or failure to create app.
5858
pub async fn start(
5959
&self,
6060
canvas_id: &str,

‎crates/egui_demo_app/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ fn main() -> Result<(), eframe::Error> {
4848
eframe::run_native(
4949
"egui demo app",
5050
options,
51-
Box::new(|cc| Box::new(egui_demo_app::WrapApp::new(cc))),
51+
Box::new(|cc| Ok(Box::new(egui_demo_app::WrapApp::new(cc)))),
5252
)
5353
}
5454

‎crates/egui_demo_app/src/web.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl WebHandle {
3232
.start(
3333
canvas_id,
3434
eframe::WebOptions::default(),
35-
Box::new(|cc| Box::new(WrapApp::new(cc))),
35+
Box::new(|cc| Ok(Box::new(WrapApp::new(cc)))),
3636
)
3737
.await
3838
}

‎examples/confirm_exit/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() -> Result<(), eframe::Error> {
1212
eframe::run_native(
1313
"Confirm exit",
1414
options,
15-
Box::new(|_cc| Box::<MyApp>::default()),
15+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
1616
)
1717
}
1818

‎examples/custom_3d_glow/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn main() -> Result<(), eframe::Error> {
1919
eframe::run_native(
2020
"Custom 3D painting in eframe using glow",
2121
options,
22-
Box::new(|cc| Box::new(MyApp::new(cc))),
22+
Box::new(|cc| Ok(Box::new(MyApp::new(cc)))),
2323
)
2424
}
2525

‎examples/custom_font/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn main() -> Result<(), eframe::Error> {
1212
eframe::run_native(
1313
"egui example: custom font",
1414
options,
15-
Box::new(|cc| Box::new(MyApp::new(cc))),
15+
Box::new(|cc| Ok(Box::new(MyApp::new(cc)))),
1616
)
1717
}
1818

‎examples/custom_font_style/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn main() -> Result<(), eframe::Error> {
1111
eframe::run_native(
1212
"egui example: global font style",
1313
options,
14-
Box::new(|cc| Box::new(MyApp::new(cc))),
14+
Box::new(|cc| Ok(Box::new(MyApp::new(cc)))),
1515
)
1616
}
1717

‎examples/custom_keypad/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() -> Result<(), eframe::Error> {
2020
// This gives us image support:
2121
egui_extras::install_image_loaders(&cc.egui_ctx);
2222

23-
Box::<MyApp>::default()
23+
Ok(Box::<MyApp>::default())
2424
}),
2525
)
2626
}

‎examples/custom_plot_manipulation/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn main() -> Result<(), eframe::Error> {
1111
eframe::run_native(
1212
"Plot",
1313
options,
14-
Box::new(|_cc| Box::<PlotExample>::default()),
14+
Box::new(|_cc| Ok(Box::<PlotExample>::default())),
1515
)
1616
}
1717

‎examples/custom_window_frame/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fn main() -> Result<(), eframe::Error> {
1919
eframe::run_native(
2020
"Custom window frame", // unused title
2121
options,
22-
Box::new(|_cc| Box::<MyApp>::default()),
22+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
2323
)
2424
}
2525

‎examples/file_dialog/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() -> Result<(), eframe::Error> {
1414
eframe::run_native(
1515
"Native file dialogs and drag-and-drop files",
1616
options,
17-
Box::new(|_cc| Box::<MyApp>::default()),
17+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
1818
)
1919
}
2020

‎examples/hello_world/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn main() -> Result<(), eframe::Error> {
1616
// This gives us image support:
1717
egui_extras::install_image_loaders(&cc.egui_ctx);
1818

19-
Box::<MyApp>::default()
19+
Ok(Box::<MyApp>::default())
2020
}),
2121
)
2222
}

‎examples/hello_world_par/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn main() -> Result<(), eframe::Error> {
1717
eframe::run_native(
1818
"My parallel egui App",
1919
options,
20-
Box::new(|_cc| Box::new(MyApp::new())),
20+
Box::new(|_cc| Ok(Box::new(MyApp::new()))),
2121
)
2222
}
2323

‎examples/images/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn main() -> Result<(), eframe::Error> {
1515
Box::new(|cc| {
1616
// This gives us image support:
1717
egui_extras::install_image_loaders(&cc.egui_ctx);
18-
Box::<MyApp>::default()
18+
Ok(Box::<MyApp>::default())
1919
}),
2020
)
2121
}

‎examples/keyboard_events/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ fn main() -> Result<(), eframe::Error> {
1010
eframe::run_native(
1111
"Keyboard events",
1212
options,
13-
Box::new(|_cc| Box::<Content>::default()),
13+
Box::new(|_cc| Ok(Box::<Content>::default())),
1414
)
1515
}
1616

‎examples/multiple_viewports/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ fn main() -> Result<(), eframe::Error> {
1717
eframe::run_native(
1818
"Multiple viewports",
1919
options,
20-
Box::new(|_cc| Box::<MyApp>::default()),
20+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
2121
)
2222
}
2323

‎examples/puffin_profiler/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn main() -> Result<(), eframe::Error> {
2222

2323
..Default::default()
2424
},
25-
Box::new(|_cc| Box::<MyApp>::default()),
25+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
2626
)
2727
}
2828

‎examples/save_plot/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() -> Result<(), eframe::Error> {
1414
eframe::run_native(
1515
"My egui App with a plot",
1616
options,
17-
Box::new(|_cc| Box::<MyApp>::default()),
17+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
1818
)
1919
}
2020

‎examples/screenshot/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn main() -> Result<(), eframe::Error> {
1414
eframe::run_native(
1515
"Take screenshots and display with eframe/egui",
1616
options,
17-
Box::new(|_cc| Box::<MyApp>::default()),
17+
Box::new(|_cc| Ok(Box::<MyApp>::default())),
1818
)
1919
}
2020

‎examples/serial_windows/src/main.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() -> Result<(), eframe::Error> {
2323
eframe::run_native(
2424
"First Window",
2525
options.clone(),
26-
Box::new(|_cc| Box::new(MyApp { has_next: true })),
26+
Box::new(|_cc| Ok(Box::new(MyApp { has_next: true }))),
2727
)?;
2828

2929
std::thread::sleep(std::time::Duration::from_secs(2));
@@ -32,7 +32,7 @@ fn main() -> Result<(), eframe::Error> {
3232
eframe::run_native(
3333
"Second Window",
3434
options.clone(),
35-
Box::new(|_cc| Box::new(MyApp { has_next: true })),
35+
Box::new(|_cc| Ok(Box::new(MyApp { has_next: true }))),
3636
)?;
3737

3838
std::thread::sleep(std::time::Duration::from_secs(2));
@@ -41,7 +41,7 @@ fn main() -> Result<(), eframe::Error> {
4141
eframe::run_native(
4242
"Third Window",
4343
options,
44-
Box::new(|_cc| Box::new(MyApp { has_next: false })),
44+
Box::new(|_cc| Ok(Box::new(MyApp { has_next: false }))),
4545
)
4646
}
4747

‎examples/user_attention/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn main() -> eframe::Result<()> {
1515
eframe::run_native(
1616
"User attention test",
1717
native_options,
18-
Box::new(|cc| Box::new(Application::new(cc))),
18+
Box::new(|cc| Ok(Box::new(Application::new(cc)))),
1919
)
2020
}
2121

‎tests/test_inline_glow_paint/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
1616
eframe::run_native(
1717
"My test app",
1818
options,
19-
Box::new(|_cc| Box::<MyTestApp>::default()),
19+
Box::new(|_cc| Ok(Box::<MyTestApp>::default())),
2020
)?;
2121
Ok(())
2222
}

‎tests/test_viewports/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ fn main() {
2222

2323
..Default::default()
2424
},
25-
Box::new(|_| Box::<App>::default()),
25+
Box::new(|_cc| Ok(Box::<App>::default())),
2626
);
2727
}
2828

0 commit comments

Comments
 (0)
Please sign in to comment.