Repository: tauri-apps/tauri
File: crates/tauri/src/app.rs (Rust)

Code before:
  }

  /// Runs the application, returning the exit code to use.
  ///
  /// # Examples
  /// ```,no_run
  /// let app = tauri::Builder::default()
  ///   // on an actual app, remove the string argument
  ///   .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json"))
  ///   .expect("error while building tauri application");
  /// let exit_code = app.run_return(|_app_handle, event| match event {
  ///   tauri::RunEvent::ExitRequested { api, .. } => {
  ///     api.prevent_exit();
  ///   }
  ///   _ => {}
  /// });
  ///
  /// std::process::exit(exit_code);
  /// ```
  pub fn run_return<F: FnMut(&AppHandle<R>, RunEvent) + 'static>(mut self, mut callback: F) -> i32 {
    let manager = self.manager.clone();
    let app_handle = self.handle().clone();

    if !self.ran_setup {
      if let Err(e) = setup(&mut self) {
        panic!("Failed to setup app: {e}");
      }
    }

    let exit_code = self.runtime.as_mut().unwrap().run_return(move |event| {
      let event = on_event_loop_event(&app_handle, event, &manager);
      callback(&app_handle, event);
    });

    self.cleanup_before_exit();

    exit_code
  }

  /// Runs an iteration of the runtime event loop and immediately return.
  ///
  /// Note that when using this API, app cleanup is not automatically done.
  /// The cleanup calls [`App::cleanup_before_exit`] so you may want to call that function before exiting the application.
  ///
  /// # Examples
  /// ```no_run
  /// use tauri::Manager;
  ///
  /// let mut app = tauri::Builder::default()
  ///   // on an actual app, remove the string argument
  ///   .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json"))

Review comment (suggestion):
We could avoid this panic if we would change the method signature to something like `Result<ExitCode, Error>`.

Code after:
        app_handle.cleanup_before_exit();
      }
      _ => {
        let event = on_event_loop_event(&app_handle, event, &manager);
        callback(&app_handle, event);
      }
    });
  }

  /// Runs the application, returning its intended exit code.
  ///
  /// ## Platform-specific
  ///
  /// - **iOS**: Unsupported. The application will fallback to [`run`](Self::run).
  ///
  /// # Panics
  ///
  /// This function will panic if the setup-function supplied in [`Builder::setup`] fails.
  ///
  /// # Examples
  /// ```,no_run
  /// let app = tauri::Builder::default()
  ///   // on an actual app, remove the string argument
  ///   .build(tauri::generate_context!("test/fixture/src-tauri/tauri.conf.json"))
  ///   .expect("error while building tauri application");
  /// let exit_code = app
  ///   .run_return(|_app_handle, event| match event {
  ///     tauri::RunEvent::ExitRequested { api, .. } => {
  ///      api.prevent_exit();
  ///     }
  ///      _ => {}
  ///   });
  ///
  /// std::process::exit(exit_code);
  /// ```
  pub fn run_return<F: FnMut(&AppHandle<R>, RunEvent) + 'static>(mut self, mut callback: F) -> i32 {
    let manager = self.manager.clone();
    let app_handle = self.handle().clone();

    self
      .runtime
      .take()
      .unwrap()
      .run_return(move |event| match event {
        RuntimeRunEvent::Ready => {
          if let Err(e) = setup(&mut self) {
            panic!("Failed to setup app: {e}");
          }
          let event = on_event_loop_event(&app_handle, RuntimeRunEvent::Ready, &manager);
          callback(&app_handle, event);
        }