Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document Emitter trait method panics #12444

Open
wants to merge 16 commits into
base: dev
Choose a base branch
from
Open

Conversation

sftse
Copy link

@sftse sftse commented Jan 19, 2025

Almost all methods of the Listener and Emitter traits take an event name and will panic if that name does not satisfy some preconditions. This is not documented and this PR fixes this. This PR also moves the panic locations closer to the user-facing code, making it immediately clear what has gone wrong and what methods were responsible for the panic. Prior to this change, the panic pointed to a location of little use to a user of tauri unless he reverse engineers how that code was called within tauri.

As a drive-by improvement, it was a bit unclear that the Emitter trait is purely defined based on methods on the AppManager. This PR makes all methods on the Emitter trait default methods and saves boilerplate. This change should not have any downsides because Emitter is a sealed trait that can only be implemented inside tauri.

@sftse sftse requested a review from a team as a code owner January 19, 2025 13:44
Copy link
Member

@amrbashir amrbashir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this LGTM, could you add a change file in .changes directory?

This PR makes all methods on the Emitter trait default methods and saves boilerplate

This was done intentionally to customize the documentation example based on the used type, but I guess it is fine to remove.

@sftse sftse requested a review from amrbashir January 20, 2025 10:32
Copy link
Contributor

github-actions bot commented Jan 20, 2025

Package Changes Through 2d63772

There are 4 changes which include tauri-bundler with patch, tauri-cli with patch, tauri with patch, @tauri-apps/cli with patch

Planned Package Versions

The following package releases are the planned based on the context of changes in this pull request.

package current next
tauri-bundler 2.2.2 2.2.3
tauri 2.2.3 2.2.4
@tauri-apps/cli 2.2.5 2.2.6
tauri-cli 2.2.5 2.2.6

Add another change file through the GitHub UI by following this link.


Read about change files or the docs at github.com/jbolda/covector

@FabianLars
Copy link
Member

Should we even panic here? It may be good for development for most cases but what if devs use dynamic event names that are derived from some http request for example?

idk panicking in a gui library just always sounds awaful to me

@amrbashir
Copy link
Member

yeah maybe returning an Error here is better, the methods already return Result type

@sftse
Copy link
Author

sftse commented Jan 21, 2025

I've added some changes that inch closer in that direction, replacing the assert with a checked EventName constructor along with some internal refactors, no longer passing &str and String but EventName<&str> and EventName<String>. I think the code structure benefits from these changes regardless of whether the panic should be removed or not. If the changes are not palatable (they're a bit larger than I originally set out to do with this PR) I can revert.

While Emitter does return an error, Listener does not, and will also panic when given bad event names. So I think it is not possible to get rid of the panics without breaking stable api.

Comment on lines +941 to +944
/// # Panics
/// Will panic if `event` contains characters other than alphanumeric, `-`, `/`, `:` and `_`
fn emit<S: Serialize + Clone>(&self, event: &str, payload: S) -> Result<()> {
let event = EventName::new(event).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of panicking here, just propagate the result from EventName::new

}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct EventName<S = String>(S);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's move this type to tauri/src/event/mod.rs

Comment on lines +37 to +38
#[derive(Clone)]
pub(crate) struct InvalidEventName;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be just a variant on tauri::Error type

Comment on lines +52 to +58
}
pub(crate) fn into_inner(self) -> S {
self.0
}
pub(crate) fn as_str_event(&self) -> EventName<&str> {
EventName(self.0.as_ref())
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
pub(crate) fn into_inner(self) -> S {
self.0
}
pub(crate) fn as_str_event(&self) -> EventName<&str> {
EventName(self.0.as_ref())
}
}
pub(crate) fn into_inner(self) -> S {
self.0
}
pub(crate) fn as_str_event(&self) -> EventName<&str> {
EventName(self.0.as_ref())
}

pub fn emit<S: Serialize + Clone>(&self, event: &str, payload: S) -> crate::Result<()> {
assert_event_name_is_valid(event);
let event = EventName::new(event).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems unnecessary since Emitter::emit does the same check

pub fn emit_filter<S, F>(&self, event: &str, payload: S, filter: F) -> crate::Result<()>
where
S: Serialize + Clone,
F: Fn(&EventTarget) -> bool,
{
assert_event_name_is_valid(event);
let event = EventName::new(event).unwrap();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

@@ -680,14 +680,14 @@ fn on_webview_event<R: Runtime>(webview: &Webview<R>, event: &WebviewEvent) -> c
paths: Some(paths),
position,
};
webview.emit_to_webview(DRAG_ENTER_EVENT, payload)?
webview.emit_to_webview(&DRAG_ENTER_EVENT, payload)?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't DRAG_ENTER_EVENT a copy type? can't we remove the &?

@@ -124,20 +111,20 @@ impl FromStr for EventTarget {
#[derive(Clone)]
pub struct EmitArgs {
/// Raw event name.
pub event_name: String,
pub event_name: EventName<String>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's remove this field and use the event field, we don't need both, see #12460 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants