44from dataclasses import dataclass
55
66import system , osenum , stub , diskutil , osinstall , asahi_firmware , m1n1 , bugs
7+ from urlcache import NetworkError
78from util import *
89
910PART_ALIGN = psize ("1MiB" )
@@ -263,11 +264,25 @@ def action_install_into_container(self, avail_parts):
263264 logging .info (f"Chosen IPSW version: { ipsw .version } " )
264265
265266 self .ins = stub .StubInstaller (self .sysinfo , self .dutil , self .osinfo )
266- self .ins .load_ipsw (ipsw )
267267 self .osins = osinstall .OSInstaller (self .dutil , self .data , template )
268- self .osins .load_package ()
268+ while True :
269+ try :
270+ self .ins .load_ipsw (ipsw )
271+ self .osins .load_package ()
272+ break
273+ except NetworkError as e :
274+ logging .error (f"Network error: { e } " )
275+ print ()
276+ p_error (f"Download failed: { e } " )
277+ p_message ("Please check your internet connection." )
278+ if not self .yesno ("Retry" ):
279+ return True
280+ print ()
269281
270- self .do_install ()
282+ try :
283+ self .do_install ()
284+ except NetworkError as e :
285+ self ._handle_post_partition_network_error (e )
271286
272287 def action_wipe (self ):
273288 p_warning ("This will wipe all data on the currently selected disk." )
@@ -280,27 +295,63 @@ def action_wipe(self):
280295 template = self .choose_os ()
281296
282297 self .osins = osinstall .OSInstaller (self .dutil , self .data , template )
283- self .osins .load_package ()
298+ while True :
299+ try :
300+ self .osins .load_package ()
301+ break
302+ except NetworkError as e :
303+ logging .error (f"Network error: { e } " )
304+ print ()
305+ p_error (f"Download failed: { e } " )
306+ p_message ("Please check your internet connection." )
307+ if not self .yesno ("Retry" ):
308+ return True
309+ print ()
284310
285311 min_size = STUB_SIZE + (self .osins .min_size if self .expert else self .osins .min_recommended_size )
286312 print ()
287313 p_message (f"Minimum required space for this OS: { ssize (min_size )} " )
288314
289315 start , end = self .dutil .get_disk_usable_range (self .cur_disk )
290- os_size = self .get_os_size_and_info (end - start , min_size , template )
316+ while True :
317+ try :
318+ os_size = self .get_os_size_and_info (end - start , min_size , template )
319+ break
320+ except NetworkError as e :
321+ logging .error (f"Network error: { e } " )
322+ print ()
323+ p_error (f"Download failed: { e } " )
324+ p_message ("Please check your internet connection." )
325+ if not self .yesno ("Retry" ):
326+ return True
327+ print ()
291328
292329 p_progress (f"Partitioning the whole disk ({ self .cur_disk } )" )
293330 self .part = self .dutil .partitionDisk (self .cur_disk , "apfs" , self .osins .name , STUB_SIZE )
294331
295332 p_progress (f"Creating new stub macOS named { self .osins .name } " )
296333 logging .info (f"Creating stub macOS: { self .osins .name } " )
297- self .do_install (os_size )
334+ try :
335+ self .do_install (os_size )
336+ except NetworkError as e :
337+ self ._handle_post_partition_network_error (e )
298338
299339 def action_install_into_free (self , avail_free ):
300340 template = self .choose_os ()
301341
302342 self .osins = osinstall .OSInstaller (self .dutil , self .data , template )
303- self .osins .load_package ()
343+ while True :
344+ try :
345+ self .osins .load_package ()
346+ break
347+ except NetworkError as e :
348+ logging .error (f"Network error: { e } " )
349+ print ()
350+ p_error (f"Download failed: { e } " )
351+ p_message ("Please check your internet connection." )
352+ if not self .yesno ("Retry" ):
353+ return True
354+ print ()
304355
305356 min_size = STUB_SIZE + (self .osins .min_size if self .expert else self .osins .min_recommended_size )
306357 print ()
@@ -327,13 +378,27 @@ def action_install_into_free(self, avail_free):
327378 print ()
328379 p_message (f"Available free space: { ssize (free_part .size )} " )
329380
330- os_size = self .get_os_size_and_info (free_part .size , min_size , template )
381+ while True :
382+ try :
383+ os_size = self .get_os_size_and_info (free_part .size , min_size , template )
384+ break
385+ except NetworkError as e :
386+ logging .error (f"Network error: { e } " )
387+ print ()
388+ p_error (f"Download failed: { e } " )
389+ p_message ("Please check your internet connection." )
390+ if not self .yesno ("Retry" ):
391+ return True
392+ print ()
331393
332394 p_progress (f"Creating new stub macOS named { self .osins .name } " )
333395 logging .info (f"Creating stub macOS: { self .osins .name } " )
334396 self .part = self .dutil .addPartition (free_part .name , "apfs" , self .osins .name , STUB_SIZE )
335397
336- self .do_install (os_size )
398+ try :
399+ self .do_install (os_size )
400+ except NetworkError as e :
401+ self ._handle_post_partition_network_error (e )
337402
338403 def get_os_size_and_info (self , free_size , min_size , template ):
339404 os_size = None
@@ -488,9 +553,19 @@ def action_rebuild_vendorfw(self, oses):
488553 p_message ("Unable to rebuild firmware" )
489554 return False
490555
491- self .ins .load_ipsw (ipsw )
492- self .ins .load_identity ()
493- self .ins .collect_firmware (fw_pkg )
556+ try :
557+ self .ins .load_ipsw (ipsw )
558+ self .ins .load_identity ()
559+ self .ins .collect_firmware (fw_pkg )
560+ except NetworkError as e :
561+ logging .error (f"Network error during firmware rebuild: { e } " )
562+ print ()
563+ p_error (f"Firmware rebuild failed: { e } " )
564+ p_message ("Please check your internet connection and try again." )
565+ print ()
566+ p_message ("Press enter to return to the main menu." )
567+ self .input ()
568+ return True
494569 fw_pkg .close ()
495570
496571 p_plain (f" Copying firmware into { target .name } partition..." )
@@ -505,6 +580,23 @@ def action_rebuild_vendorfw(self, oses):
505580
506581 return True
507582
583+ def _handle_post_partition_network_error (self , e ):
584+ logging .error (f"Network error during installation: { e } " )
585+ print ()
586+ p_error ("Installation failed due to a network error." )
587+ p_error (f" { e } " )
588+ print ()
589+ p_message ("Please check your internet connection, then re-run the installer." )
590+ p_message ("The installer will detect the incomplete installation and offer" )
591+ p_message ("to repair it." )
592+ print ()
593+ p_warning ("If you need to file a bug report, please attach the log file:" )
594+ p_warning (f" { os .getcwd ()} /installer.log" )
595+ print ()
596+ p_message ("Press enter to exit." )
597+ self .input ()
598+ sys .exit (1 )
599+
508600 def do_install (self , total_size = None ):
509601 p_progress (f"Installing stub macOS into { self .part .name } ({ self .part .label } )" )
510602
@@ -1151,6 +1243,13 @@ def main_loop(self):
11511243 print ()
11521244 logging .info ("KeyboardInterrupt" )
11531245 p_error ("Interrupted" )
1246+ except NetworkError as e :
1247+ logging .exception ("Network error" )
1248+ p_error (f"Installation failed due to a network error: { e } " )
1249+ print ()
1250+ p_message ("Please check your internet connection and try again." )
1251+ p_warning ("If you need to file a bug report, please attach the log file:" )
1252+ p_warning (f" { os .getcwd ()} /installer.log" )
11541253 except subprocess .CalledProcessError as e :
11551254 cmd = shlex .join (e .cmd )
11561255 p_error (f"Failed to run process: { cmd } " )
0 commit comments