2020from reflex import constants
2121from reflex .config import environment
2222from reflex .utils import console , path_ops , prerequisites
23+ from reflex .utils .registry import get_npm_registry
2324
2425
2526def kill (pid : int ):
@@ -276,6 +277,7 @@ def stream_logs(
276277 progress : Progress | None = None ,
277278 suppress_errors : bool = False ,
278279 analytics_enabled : bool = False ,
280+ prior_logs : Tuple [tuple [str , ...], ...] = (),
279281):
280282 """Stream the logs for a process.
281283
@@ -285,6 +287,7 @@ def stream_logs(
285287 progress: The ongoing progress bar if one is being used.
286288 suppress_errors: If True, do not exit if errors are encountered (for fallback).
287289 analytics_enabled: Whether analytics are enabled for this command.
290+ prior_logs: The logs of the prior processes that have been run.
288291
289292 Yields:
290293 The lines of the process output.
@@ -312,8 +315,31 @@ def stream_logs(
312315 accepted_return_codes = [0 , - 2 , 15 ] if constants .IS_WINDOWS else [0 , - 2 ]
313316 if process .returncode not in accepted_return_codes and not suppress_errors :
314317 console .error (f"{ message } failed with exit code { process .returncode } " )
315- for line in logs :
316- console .error (line , end = "" )
318+ if "" .join (logs ).count ("CERT_HAS_EXPIRED" ) > 0 :
319+ bunfig = prerequisites .get_web_dir () / constants .Bun .CONFIG_PATH
320+ npm_registry_line = next (
321+ (
322+ line
323+ for line in bunfig .read_text ().splitlines ()
324+ if line .startswith ("registry" )
325+ ),
326+ None ,
327+ )
328+ if not npm_registry_line or "=" not in npm_registry_line :
329+ npm_registry = get_npm_registry ()
330+ else :
331+ npm_registry = npm_registry_line .split ("=" )[1 ].strip ()
332+ console .error (
333+ f"Failed to fetch securely from [bold]{ npm_registry } [/bold]. Please check your network connection. "
334+ "You can try running the command again or changing the registry by setting the "
335+ "NPM_CONFIG_REGISTRY environment variable. If TLS is the issue, and you know what "
336+ "you are doing, you can disable it by setting the SSL_NO_VERIFY environment variable."
337+ )
338+ raise typer .Exit (1 )
339+ for set_of_logs in (* prior_logs , tuple (logs )):
340+ for line in set_of_logs :
341+ console .error (line , end = "" )
342+ console .error ("\n \n " )
317343 if analytics_enabled :
318344 telemetry .send ("error" , context = message )
319345 console .error ("Run with [bold]--loglevel debug [/bold] for the full log." )
@@ -336,26 +362,33 @@ def show_status(
336362 process : subprocess .Popen ,
337363 suppress_errors : bool = False ,
338364 analytics_enabled : bool = False ,
339- prior_processes : Tuple [subprocess . Popen , ...] = (),
340- ):
365+ prior_logs : Tuple [tuple [ str , ...] , ...] = (),
366+ ) -> list [ str ] :
341367 """Show the status of a process.
342368
343369 Args:
344370 message: The initial message to display.
345371 process: The process.
346372 suppress_errors: If True, do not exit if errors are encountered (for fallback).
347373 analytics_enabled: Whether analytics are enabled for this command.
348- prior_processes: The prior processes that have been run.
374+ prior_logs: The logs of the prior processes that have been run.
375+
376+ Returns:
377+ The lines of the process output.
349378 """
350- for one_process in (* prior_processes , process ):
351- with console .status (message ) as status :
352- for line in stream_logs (
353- message ,
354- one_process ,
355- suppress_errors = suppress_errors ,
356- analytics_enabled = analytics_enabled ,
357- ):
358- status .update (f"{ message } { line } " )
379+ lines = []
380+
381+ with console .status (message ) as status :
382+ for line in stream_logs (
383+ message ,
384+ process ,
385+ suppress_errors = suppress_errors ,
386+ analytics_enabled = analytics_enabled ,
387+ prior_logs = prior_logs ,
388+ ):
389+ status .update (f"{ message } { line } " )
390+ lines .append (line )
391+ return lines
359392
360393
361394def show_progress (message : str , process : subprocess .Popen , checkpoints : list [str ]):
@@ -409,7 +442,7 @@ def run_process_with_fallbacks(
409442 show_status_message : str ,
410443 fallbacks : str | Sequence [str ] | Sequence [Sequence [str ]] | None = None ,
411444 analytics_enabled : bool = False ,
412- prior_processes : Tuple [subprocess . Popen , ...] = (),
445+ prior_logs : Tuple [tuple [ str , ...] , ...] = (),
413446 ** kwargs ,
414447):
415448 """Run subprocess and retry using fallback command if initial command fails.
@@ -419,7 +452,7 @@ def run_process_with_fallbacks(
419452 show_status_message: The status message to be displayed in the console.
420453 fallbacks: The fallback command to run if the initial command fails.
421454 analytics_enabled: Whether analytics are enabled for this command.
422- prior_processes : The prior processes that have been run.
455+ prior_logs : The logs of the prior processes that have been run.
423456 **kwargs: Kwargs to pass to new_process function.
424457 """
425458 process = new_process (get_command_with_loglevel (args ), ** kwargs )
@@ -429,11 +462,11 @@ def run_process_with_fallbacks(
429462 show_status_message ,
430463 process ,
431464 analytics_enabled = analytics_enabled ,
432- prior_processes = prior_processes ,
465+ prior_logs = prior_logs ,
433466 )
434467 else :
435468 # Suppress errors for initial command, because we will try to fallback
436- show_status (show_status_message , process , suppress_errors = True )
469+ logs = show_status (show_status_message , process , suppress_errors = True )
437470
438471 current_fallback = fallbacks [0 ] if not isinstance (fallbacks , str ) else fallbacks
439472 next_fallbacks = fallbacks [1 :] if not isinstance (fallbacks , str ) else None
@@ -453,7 +486,7 @@ def run_process_with_fallbacks(
453486 show_status_message = show_status_message ,
454487 fallbacks = next_fallbacks ,
455488 analytics_enabled = analytics_enabled ,
456- prior_processes = (* prior_processes , process ),
489+ prior_logs = (* prior_logs , tuple ( logs ) ),
457490 ** kwargs ,
458491 )
459492
0 commit comments