@@ -622,27 +622,36 @@ impl StaticExporterBuilder {
622622
623623 /// Create a new WebDriver instance based on the spawn_webdriver flag
624624 fn create_webdriver ( & self ) -> Result < WebDriver > {
625- match self . spawn_webdriver {
626- // Try to connect to existing WebDriver or spawn new if not available
627- true => WebDriver :: connect_or_spawn ( self . webdriver_port ) ,
628- // Create the WebDriver instance without spawning
629- false => WebDriver :: new ( self . webdriver_port ) ,
630- }
625+ let port = self . webdriver_port ;
626+ let in_async = tokio:: runtime:: Handle :: try_current ( ) . is_ok ( ) ;
627+
628+ let run_create_fn = |spawn : bool | -> Result < WebDriver > {
629+ let work = move || {
630+ if spawn {
631+ WebDriver :: connect_or_spawn ( port)
632+ } else {
633+ WebDriver :: new ( port)
634+ }
635+ } ;
636+ if in_async {
637+ std:: thread:: spawn ( work)
638+ . join ( )
639+ . map_err ( |_| anyhow ! ( "failed to join webdriver thread" ) ) ?
640+ } else {
641+ work ( )
642+ }
643+ } ;
644+
645+ run_create_fn ( self . spawn_webdriver )
631646 }
632647}
633648
634- // Async builder for async-first exporter (added without reordering existing items)
649+ // Async builder for async-first exporter (added without reordering existing
650+ // items)
635651impl StaticExporterBuilder {
636652 /// Build an async exporter for use within async contexts.
637653 pub fn build_async ( & self ) -> Result < AsyncStaticExporter > {
638- let wd = if self . spawn_webdriver {
639- let port = self . webdriver_port ;
640- std:: thread:: spawn ( move || WebDriver :: connect_or_spawn ( port) )
641- . join ( )
642- . map_err ( |_| anyhow ! ( "failed to join webdriver spawn thread" ) ) ??
643- } else {
644- WebDriver :: new ( self . webdriver_port ) ?
645- } ;
654+ let wd = self . create_webdriver ( ) ?;
646655 Ok ( AsyncStaticExporter {
647656 webdriver_port : self . webdriver_port ,
648657 webdriver_url : self . webdriver_url . clone ( ) ,
@@ -760,6 +769,13 @@ impl StaticExporter {
760769 height : usize ,
761770 scale : f64 ,
762771 ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
772+ if tokio:: runtime:: Handle :: try_current ( ) . is_ok ( ) {
773+ return Err ( anyhow ! (
774+ "StaticExporter sync methods cannot be used inside an async context. \
775+ Use StaticExporterBuilder::build_async() and the associated AsyncStaticExporter::write_fig(...)."
776+ )
777+ . into ( ) ) ;
778+ }
763779 let rt = self . runtime . clone ( ) ;
764780 rt. block_on (
765781 self . inner
@@ -818,17 +834,20 @@ impl StaticExporter {
818834 height : usize ,
819835 scale : f64 ,
820836 ) -> Result < String , Box < dyn std:: error:: Error > > {
837+ if tokio:: runtime:: Handle :: try_current ( ) . is_ok ( ) {
838+ return Err ( anyhow ! (
839+ "StaticExporter sync methods cannot be used inside an async context. \
840+ Use StaticExporterBuilder::build_async() and the associated AsyncStaticExporter::write_to_string(...)."
841+ )
842+ . into ( ) ) ;
843+ }
821844 let rt = self . runtime . clone ( ) ;
822845 rt. block_on (
823846 self . inner
824847 . write_to_string ( plot, format, width, height, scale) ,
825848 )
826849 }
827850
828- /// Convert the Plotly graph to a static image using Kaleido and return the
829- /// result as a String
830- // Removed internal export/extract in favor of delegating to AsyncStaticExporter
831-
832851 fn extract_plain ( payload : & str , format : & ImageFormat ) -> Result < String > {
833852 match payload. split_once ( "," ) {
834853 Some ( ( type_info, data) ) => {
@@ -930,16 +949,11 @@ impl StaticExporter {
930949 }
931950
932951 /// Explicitly close the WebDriver session and stop the driver.
933- /// Prefer calling this in long-running applications to ensure deterministic cleanup.
952+ /// Prefer calling this in long-running applications to ensure deterministic
953+ /// cleanup.
934954 pub fn close ( & mut self ) {
935- if let Some ( client) = self . inner . webdriver_client . take ( ) {
936- let runtime = self . runtime . clone ( ) ;
937- runtime. block_on ( async {
938- if let Err ( e) = client. close ( ) . await {
939- error ! ( "Failed to close WebDriver client: {e}" ) ;
940- }
941- } ) ;
942- }
955+ let runtime = self . runtime . clone ( ) ;
956+ runtime. block_on ( self . inner . close ( ) ) ;
943957 }
944958}
945959
0 commit comments