1616pub mod config;
1717pub mod router;
1818
19- use chromiumoxide:: { browser:: Browser , cdp:: browser_protocol:: page:: PrintToPdfParams , Page } ;
19+ use chromiumoxide:: {
20+ browser:: Browser ,
21+ cdp:: browser_protocol:: page:: { CaptureScreenshotParamsBuilder , PrintToPdfParams } ,
22+ Page ,
23+ } ;
2024use config:: { get_chrome_launch_options, CONFIG } ;
2125use futures:: StreamExt ;
2226use lettre:: {
@@ -165,9 +169,13 @@ pub async fn generate_report(
165169 }
166170 Err ( e) => {
167171 let page_url = page. url ( ) . await ;
172+ // Take a screenshot before killing the browser to help debug login issues
173+ take_screenshot ( & page, org_id, dashboard_id) . await ?;
174+ log:: info!( "killing browser" ) ;
168175 browser. close ( ) . await ?;
169176 browser. wait ( ) . await ?;
170177 handle. await ?;
178+ browser. kill ( ) . await ;
171179 let err_msg = format ! (
172180 "Error finding email input box: current url: {:#?} error: {e}" ,
173181 page_url
@@ -189,9 +197,12 @@ pub async fn generate_report(
189197 }
190198 Err ( e) => {
191199 let page_url = page. url ( ) . await ;
200+ take_screenshot ( & page, org_id, dashboard_id) . await ?;
201+ log:: info!( "killing browser" ) ;
192202 browser. close ( ) . await ?;
193203 browser. wait ( ) . await ?;
194204 handle. await ?;
205+ browser. kill ( ) . await ;
195206 let err_msg = format ! (
196207 "Error finding password input box: current url: {:#?} error: {e}" ,
197208 page_url
@@ -285,9 +296,13 @@ pub async fn generate_report(
285296 . await
286297 {
287298 let page_url = page. url ( ) . await ;
299+ // Take a screenshot before killing the browser to help debug issues
300+ take_screenshot ( & page, org_id, dashboard_id) . await ?;
301+ log:: info!( "killing browser" ) ;
288302 browser. close ( ) . await ?;
289303 browser. wait ( ) . await ?;
290304 handle. await ?;
305+ browser. kill ( ) . await ;
291306 log:: error!(
292307 "Error navigating to organization {org_id}: current uri: {:#?} error: {e}" ,
293308 page_url
@@ -302,9 +317,12 @@ pub async fn generate_report(
302317
303318 if let Err ( e) = page. goto ( & dashb_url) . await {
304319 let page_url = page. url ( ) . await ;
320+ take_screenshot ( & page, org_id, dashboard_id) . await ?;
321+ log:: info!( "killing browser" ) ;
305322 browser. close ( ) . await ?;
306323 browser. wait ( ) . await ?;
307324 handle. await ?;
325+ browser. kill ( ) . await ;
308326 log:: error!(
309327 "Error navigating to dashboard url {dashb_url}: current uri: {:#?} error: {e}" ,
310328 page_url
@@ -335,19 +353,27 @@ pub async fn generate_report(
335353
336354 if let Err ( e) = page. find_element ( "main" ) . await {
337355 let page_url = page. url ( ) . await ;
356+ take_screenshot ( & page, org_id, dashboard_id) . await ?;
357+ // Take a screenshot before killing the browser to help debug login issues
358+ log:: info!( "killing browser" ) ;
338359 browser. close ( ) . await ?;
339360 browser. wait ( ) . await ?;
340361 handle. await ?;
362+ browser. kill ( ) . await ;
341363 return Err ( anyhow:: anyhow!(
342364 "[REPORT] main html element not rendered yet for dashboard {dashboard_id}; most likely login failed: current url: {:#?} error: {e}" ,
343365 page_url
344366 ) ) ;
345367 }
346368 if let Err ( e) = page. find_element ( "div.displayDiv" ) . await {
347369 let page_url = page. url ( ) . await ;
370+ // Take a screenshot before killing the browser to help debug login issues
371+ take_screenshot ( & page, org_id, dashboard_id) . await ?;
372+ log:: info!( "killing browser" ) ;
348373 browser. close ( ) . await ?;
349374 browser. wait ( ) . await ?;
350375 handle. await ?;
376+ browser. kill ( ) . await ;
351377 return Err ( anyhow:: anyhow!(
352378 "[REPORT] div.displayDiv element not rendered yet for dashboard {dashboard_id}: current url: {:#?} error: {e}" ,
353379 page_url
@@ -373,6 +399,7 @@ pub async fn generate_report(
373399 browser. close ( ) . await ?;
374400 browser. wait ( ) . await ?;
375401 handle. await ?;
402+ browser. kill ( ) . await ;
376403 log:: debug!( "done with headless browser" ) ;
377404 Ok ( ( pdf_data, email_dashb_url) )
378405}
@@ -430,6 +457,22 @@ async fn send_email(
430457 }
431458}
432459
460+ async fn take_screenshot (
461+ page : & Page ,
462+ org_id : & str ,
463+ dashboard_name : & str ,
464+ ) -> Result < ( ) , anyhow:: Error > {
465+ let timestamp = chrono:: Utc :: now ( ) . timestamp ( ) ;
466+ let screenshot_params = CaptureScreenshotParamsBuilder :: default ( ) ;
467+ let screenshot = page. screenshot ( screenshot_params. build ( ) ) . await ?;
468+ tokio:: fs:: write (
469+ format ! ( "screenshot_{}_{}_{}.png" , org_id, dashboard_name, timestamp) ,
470+ & screenshot,
471+ )
472+ . await ?;
473+ Ok ( ( ) )
474+ }
475+
433476pub async fn wait_for_panel_data_load ( page : & Page ) -> Result < Duration , anyhow:: Error > {
434477 let start = std:: time:: Instant :: now ( ) ;
435478 let timeout = std:: time:: Duration :: from_secs ( CONFIG . chrome . chrome_sleep_secs . into ( ) ) ;
@@ -456,6 +499,12 @@ pub async fn wait_for_panel_data_load(page: &Page) -> Result<Duration, anyhow::E
456499fn sanitize_filename ( filename : & str ) -> String {
457500 filename
458501 . chars ( )
459- . map ( |c| if c. is_ascii_alphanumeric ( ) || c == '-' || c == '_' || c == ' ' { c } else { '_' } )
502+ . map ( |c| {
503+ if c. is_ascii_alphanumeric ( ) || c == '-' || c == '_' || c == ' ' {
504+ c
505+ } else {
506+ '_'
507+ }
508+ } )
460509 . collect ( )
461- }
510+ }
0 commit comments