@@ -2390,40 +2390,65 @@ server_preview_handlers <- function(input, output, session, survey_exists) {
23902390 data = preview_port , # Store port in data for access in filter
23912391 filter = function (port_data , req ) {
23922392 port <- port_data
2393- tryCatch({
2394- # Build the target URL for the preview server
2395- target_url <- paste0(" http://127.0.0.1:" , port , req $ PATH_INFO )
2396- if (! is.null(req $ QUERY_STRING ) && nzchar(req $ QUERY_STRING )) {
2397- target_url <- paste0(target_url , " ?" , req $ QUERY_STRING )
2393+
2394+ # Build the target URL for the preview server
2395+ target_url <- paste0(" http://127.0.0.1:" , port , req $ PATH_INFO )
2396+ if (! is.null(req $ QUERY_STRING ) && nzchar(req $ QUERY_STRING )) {
2397+ target_url <- paste0(target_url , " ?" , req $ QUERY_STRING )
2398+ }
2399+
2400+ # Retry logic: try up to 3 times with delays
2401+ max_attempts <- 3
2402+ for (attempt in 1 : max_attempts ) {
2403+ result <- tryCatch({
2404+ # Forward the request to preview server
2405+ response <- httr2 :: request(target_url ) | >
2406+ httr2 :: req_timeout(10 ) | >
2407+ httr2 :: req_error(is_error = \(resp ) FALSE ) | >
2408+ httr2 :: req_perform()
2409+
2410+ # Return proxied response
2411+ list (
2412+ status = httr2 :: resp_status(response ),
2413+ headers = as.list(httr2 :: resp_headers(response )),
2414+ body = httr2 :: resp_body_raw(response )
2415+ )
2416+ }, error = function (e ) {
2417+ NULL # Return NULL to trigger retry
2418+ })
2419+
2420+ if (! is.null(result )) {
2421+ return (result ) # Success!
23982422 }
23992423
2400- # Forward the request to preview server
2401- response <- httr2 :: request(target_url ) | >
2402- httr2 :: req_timeout(30 ) | >
2403- httr2 :: req_error(is_error = \(resp ) FALSE ) | >
2404- httr2 :: req_perform()
2405-
2406- # Return proxied response
2407- list (
2408- status = httr2 :: resp_status(response ),
2409- headers = as.list(httr2 :: resp_headers(response )),
2410- body = httr2 :: resp_body_raw(response )
2411- )
2412- }, error = function (e ) {
2413- # Return error page if preview not ready
2414- list (
2415- status = 503L ,
2416- headers = list (" Content-Type" = " text/html; charset=utf-8" ),
2417- body = charToRaw(paste0(
2418- " <!DOCTYPE html><html><body style='font-family: sans-serif; padding: 40px; text-align: center;'>" ,
2419- " <h3 style='color: #dc3545;'>Preview Server Not Ready</h3>" ,
2420- " <p>Please wait a moment for the preview to start...</p>" ,
2421- " <p style='color: #666; font-size: 0.9em;'>Error: " , e $ message , " </p>" ,
2422- " <button onclick='location.reload()' style='margin-top: 20px; padding: 10px 20px;'>Retry</button>" ,
2423- " </body></html>"
2424- ))
2425- )
2426- })
2424+ # Wait before retry (except on last attempt)
2425+ if (attempt < max_attempts ) {
2426+ Sys.sleep(1 )
2427+ }
2428+ }
2429+
2430+ # All attempts failed - return error page with auto-reload
2431+ list (
2432+ status = 503L ,
2433+ headers = list (
2434+ " Content-Type" = " text/html; charset=utf-8" ,
2435+ " Refresh" = " 3" # Auto-reload after 3 seconds
2436+ ),
2437+ body = charToRaw(paste0(
2438+ " <!DOCTYPE html><html><head>" ,
2439+ " <meta http-equiv='refresh' content='3'>" ,
2440+ " </head><body style='font-family: sans-serif; padding: 40px; text-align: center;'>" ,
2441+ " <h3 style='color: #dc3545;'>Preview Server Starting...</h3>" ,
2442+ " <p>The preview is loading, please wait...</p>" ,
2443+ " <p style='color: #666; font-size: 0.9em;'>This page will refresh automatically.</p>" ,
2444+ " <div style='margin-top: 20px;'>" ,
2445+ " <div style='display: inline-block; width: 40px; height: 40px; border: 4px solid #f3f3f3; " ,
2446+ " border-top: 4px solid #3498db; border-radius: 50%; animation: spin 1s linear infinite;'></div>" ,
2447+ " </div>" ,
2448+ " <style>@keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }</style>" ,
2449+ " </body></html>"
2450+ ))
2451+ )
24272452 }
24282453 )
24292454
0 commit comments