55import signal
66import sys
77import threading
8+ import traceback
89from pathlib import Path
10+ from types import TracebackType
911from typing import Optional
1012
1113import yaml
5860def print_exit_summary (
5961 run_state : RunState ,
6062 spec_filename : str ,
63+ error_message : Optional [str ] = None ,
64+ verbose : bool = False ,
65+ exc_info : Optional [tuple [type [BaseException ] | None , BaseException | None , TracebackType | None ]] = None ,
6166) -> None :
6267 console .quiet = False
6368 """Print render outcome after the TUI exits (terminal restored)."""
69+
6470 msg = "\n [#79FC96]✓ rendering completed\n \n " if run_state .render_succeeded else "[#FF6B6B]✗ rendering failed\n \n "
6571 msg += f" [#8E8F91]render id:\t \t \t [#FFFFFF]{ run_state .render_id } \n "
6672 msg += f" [#8E8F91]input file:\t \t \t [#FFFFFF]{ spec_filename } \n "
6773 msg += f" [#8E8F91]generated code folder:\t [#FFFFFF]{ run_state .render_generated_code_path or '-' } \n \n "
6874 msg += f"[#8E8F91]functionalities [#FFFFFF]{ run_state .rendered_functionalities } [#8E8F91]used credits [#FFFFFF]{ run_state .rendered_functionalities } [#8E8F91]render time [#FFFFFF]{ format_duration_hms (run_state .render_time )} \n "
6975 console .info (msg )
76+
77+ if not run_state .render_succeeded and error_message :
78+ console .error (error_message )
79+ if verbose and exc_info and exc_info [0 ] is not None :
80+ console .error ("" .join (traceback .format_exception (* exc_info )))
7081 console .quiet = True
7182
7283
@@ -316,6 +327,8 @@ def main(): # noqa: C901
316327 setup_logging (args , event_bus , args .log_to_file , args .log_file_name , args .filename , args .headless )
317328
318329 exc_info = None
330+ error_message = None
331+
319332 try :
320333 # Validate API key is present
321334 if not args .api_key :
@@ -324,76 +337,62 @@ def main(): # noqa: C901
324337 )
325338 render (args , run_state , event_bus )
326339 except InvalidFridArgument as e :
327- exc_info = sys .exc_info ()
328- console .error (f"Invalid FRID argument: { str (e )} .\n " )
340+ error_message = f"Invalid FRID argument: { str (e )} .\n "
329341 except FileNotFoundError as e :
330- exc_info = sys . exc_info ()
331- console . error ( f"File not found: { str ( e ) } \n " )
332- console . debug ( f"Render ID : { run_state . render_id } " )
342+ error_message = f"File not found: { str ( e ) } \n "
343+ except MissingResource as e :
344+ error_message = f"Missing resource : { str ( e ) } \n "
333345 except TemplateNotFoundError as e :
334- exc_info = sys .exc_info ()
335- console .error (f"Template not found: { str (e )} \n " )
336- console .error (system_config .get_error_message ("template_not_found" ))
346+ error_message = f"""Template not found: { str (e )} \n
347+ The required template could not be found. Templates are searched in the following order (highest to lowest precedence):
348+
349+ 1. The directory containing your .plain file
350+ 2. The directory specified by --template-dir (if provided)
351+ 3. The built-in 'standard_template_library' directory
352+
353+ Please ensure that the missing template exists in one of these locations, or specify the correct --template-dir if using custom templates.
354+ """
337355 except PlainSyntaxError as e :
338- exc_info = sys .exc_info ()
339- console .error (f"Plain syntax error: { str (e )} \n " )
356+ error_message = f"Plain syntax error: { str (e )} \n "
340357 except KeyboardInterrupt :
341- exc_info = sys .exc_info ()
342- console .error ("Keyboard interrupt" )
343- console .debug (f"Render ID: { run_state .render_id } " )
358+ error_message = "Keyboard interrupt"
344359 except RequestException as e :
345- exc_info = sys .exc_info ()
346- console .error (f"Error rendering plain code: { str (e )} \n " )
347- console .debug (f"Render ID: { run_state .render_id } " )
360+ error_message = f"Error rendering plain code: { str (e )} \n "
348361 except MissingPreviousFunctionalitiesError as e :
349- exc_info = sys .exc_info ()
350- console .error (f"Error rendering plain code: { str (e )} \n " )
351- console .debug (f"Render ID: { run_state .render_id } " )
362+ error_message = f"Error rendering plain code: { str (e )} \n "
352363 except MissingAPIKey as e :
353- console . error ( f"Missing API key: { str (e )} \n " )
364+ error_message = f"Missing API key: { str (e )} \n "
354365 except InvalidAPIKey as e :
355- console . error ( f"Invalid API key: { str (e )} \n " )
366+ error_message = f"Invalid API key: { str (e )} \n "
356367 except OutdatedClientVersion as e :
357- console . error ( f"Outdated client version: { str (e )} \n " )
368+ error_message = f"Outdated client version: { str (e )} \n "
358369 except (InternalServerError , InternalClientError ):
359370 exc_info = sys .exc_info ()
360- console .error (
361- f"Internal server error.\n \n Please report the error to support@codeplain.ai with the attached { args .log_file_name } file."
362- )
363- console .debug (f"Render ID: { run_state .render_id } " )
371+ error_message = f"Internal server error.\n \n Please report the error to support@codeplain.ai with the attached { args .log_file_name } file."
364372 except ConflictingRequirements as e :
365- exc_info = sys .exc_info ()
366- console .error (f"Conflicting requirements: { str (e )} \n " )
367- console .debug (f"Render ID: { run_state .render_id } " )
373+ error_message = f"Conflicting requirements: { str (e )} \n "
368374 except RenderingCreditBalanceTooLow as e :
369- exc_info = sys .exc_info ()
370- console .error (f"Credit balance too low: { str (e )} \n " )
371- console .debug (f"Render ID: { run_state .render_id } " )
375+ error_message = f"Credit balance too low: { str (e )} \n "
372376 except LLMInternalError as e :
373377 exc_info = sys .exc_info ()
374- console .error (f"LLM internal error: { str (e )} \n " )
375- console .debug (f"Render ID: { run_state .render_id } " )
376- except MissingResource as e :
377- exc_info = sys .exc_info ()
378- console .error (f"Missing resource: { str (e )} \n " )
379- console .debug (f"Render ID: { run_state .render_id } " )
378+ error_message = f"LLM internal error: { str (e )} \n "
380379 except NetworkConnectionError as e :
381- exc_info = sys .exc_info ()
382- console .error (f"Connection error: { str (e )} \n " )
383- console .error ("Please check that your internet connection is working." )
380+ error_message = f"Connection error: { str (e )} \n \n Please check that your internet connection is working."
384381 except ModuleDoesNotExistError as e :
385- exc_info = sys .exc_info ()
386- console .error (f"Module does not exist: { str (e )} \n " )
387- console .debug (f"Render ID: { run_state .render_id } " )
382+ error_message = str (e )
388383 except Exception as e :
389384 exc_info = sys .exc_info ()
390- console .error (f"Error rendering plain code: { str (e )} \n " )
391- console .debug (f"Render ID: { run_state .render_id } " )
385+ error_message = f"Error rendering plain code: { str (e )} \n "
392386 finally :
393- print_exit_summary (run_state , args .filename )
387+ print_exit_summary (
388+ run_state ,
389+ args .filename ,
390+ error_message = error_message ,
391+ verbose = args .verbose ,
392+ exc_info = exc_info ,
393+ )
394394 if exc_info :
395- # Log traceback using the logging system
396- logging .error ("Render crashed with exception:" , exc_info = exc_info )
395+ # Log traceback
397396 dump_crash_logs (args )
398397
399398
0 commit comments