Repository: swc-project/swc
File: crates/swc/src/plugin.rs (Rust)

Code before:
        unresolved_mark,
        plugin_runtime,
    })
}

#[cfg(feature = "plugin")]
struct RustPlugins {
    plugins: Option<Vec<PluginConfig>>,
    plugin_env_vars: Option<std::sync::Arc<Vec<Atom>>>,
    metadata_context: std::sync::Arc<swc_common::plugin::metadata::TransformPluginMetadataContext>,
    comments: Option<swc_common::comments::SingleThreadedComments>,
    source_map: std::sync::Arc<swc_common::SourceMap>,
    unresolved_mark: swc_common::Mark,
    plugin_runtime: Arc<dyn PluginRuntime>,
}

#[cfg(feature = "plugin")]
impl RustPlugins {
    #[cfg(feature = "plugin")]
    fn apply(&mut self, n: Program) -> Result<Program, anyhow::Error> {
        if self.plugins.is_none() || self.plugins.as_ref().unwrap().is_empty() {
            return Ok(n);
        }

        #[cfg(feature = "manual-tokio-runtime")]
        let ret = self.apply_inner(n);

        #[cfg(not(feature = "manual-tokio-runtime"))]
        let ret = {
            use anyhow::Context;
            let filename = self.metadata_context.filename.clone();
            let fut = async move { self.apply_inner(n) };
            if let Ok(handle) = tokio::runtime::Handle::try_current() {
                handle.block_on(fut)
            } else {
                SHARED_RUNTIME.block_on(fut)
            }
            .with_context(|| format!("failed to invoke plugin on '{filename:?}'"))
        };

        ret
    }

    #[tracing::instrument(level = "info", skip_all, name = "apply_plugins")]
    #[cfg(all(feature = "plugin", not(target_arch = "wasm32")))]
    fn apply_inner(&mut self, n: Program) -> Result<Program, anyhow::Error> {
        use anyhow::Context;
        use swc_common::plugin::serialized::PluginSerializedBytes;

        // swc_plugin_macro will not inject proxy to the comments if comments is empty
        let should_enable_comments_proxy = self.comments.is_some();

Review comment (bug):
The `manual-tokio-runtime` code path doesn't include the error context that the non-manual path has. When `apply_inner` fails, the error won't include the helpful context message `'failed to invoke plugin on '{filename:?}'`. Consider adding `.with_context()` here for consistency: `let ret = self.apply_inner(n).with_context(|| format!(\"failed to invoke plugin on '{:?}'\", self.metadata_context.filename));`
```suggestion
        let ret = self
            .apply_inner(n)
            .with_context(|| format!("failed to invoke plugin on '{:?}'", self.metadata_context.filename));
```

Code after:
        unresolved_mark,
        plugin_runtime,
    })
}

#[cfg(feature = "plugin")]
struct RustPlugins {
    plugins: Option<Vec<PluginConfig>>,
    plugin_env_vars: Option<std::sync::Arc<Vec<Atom>>>,
    metadata_context: std::sync::Arc<swc_common::plugin::metadata::TransformPluginMetadataContext>,
    comments: Option<swc_common::comments::SingleThreadedComments>,
    source_map: std::sync::Arc<swc_common::SourceMap>,
    unresolved_mark: swc_common::Mark,
    plugin_runtime: Arc<dyn PluginRuntime>,
}

#[cfg(feature = "plugin")]
impl RustPlugins {
    #[cfg(feature = "plugin")]
    fn apply(&mut self, n: Program) -> Result<Program, anyhow::Error> {
        use anyhow::Context;

        if self.plugins.is_none() || self.plugins.as_ref().unwrap().is_empty() {
            return Ok(n);
        }

        let filename = self.metadata_context.filename.clone();

        #[cfg(feature = "manual-tokio-runtime")]
        let ret = self
            .apply_inner(n)
            .with_context(|| format!("failed to invoke plugin on '{filename:?}'"));

        #[cfg(not(feature = "manual-tokio-runtime"))]
        let ret = {
            let fut = async move { self.apply_inner(n) };
            if let Ok(handle) = tokio::runtime::Handle::try_current() {
                handle.block_on(fut)
            } else {
                SHARED_RUNTIME.block_on(fut)
            }
            .with_context(|| format!("failed to invoke plugin on '{filename:?}'"))
        };

        ret
    }

    #[tracing::instrument(level = "info", skip_all, name = "apply_plugins")]
    #[cfg(all(feature = "plugin", not(target_arch = "wasm32")))]
    fn apply_inner(&mut self, n: Program) -> Result<Program, anyhow::Error> {
        use anyhow::Context;