Source code for cwatm.management_modules.messages

# -------------------------------------------------------------------------
# Name:        Messages  
# Purpose:     Error handling and message system for CWatM
#
# Author:      burekpe
# Created:     16/05/2016
# CWatM is licensed under GNU GENERAL PUBLIC LICENSE Version 3.
# -------------------------------------------------------------------------

"""
Error handling and user communication system for CWatM.

This module provides a comprehensive error handling framework for the Community
Water Model, including specialized error classes for different types of failures
and user communication. The system provides clear, formatted error messages
with diagnostic information to help users identify and resolve issues.

Classes
-------
CWATMError : Base error class for general CWatM errors
CWATMFileError : Specialized error class for file-related issues
CWATMDirError : Specialized error class for directory-related issues  
CWATMWarning : Warning class for non-fatal issues
CWATMRunInfo : Information class for simulation status messages

Notes
-----
All error classes automatically extract error numbers from message strings
and provide formatted output with consistent headers. The system suppresses
Python traceback information to provide cleaner error messages for end users.
"""


import os
import sys


[docs]class CWATMError(Warning): """ Base error handling class for CWatM errors. This class provides standardized error reporting with formatted output and automatic error number extraction. It suppresses Python tracebacks to provide cleaner error messages for end users. Parameters ---------- msg : str Error message string, optionally containing error number in format "Error XXX: message" where XXX is a 3-digit error code Notes ----- Error numbers are automatically extracted from message strings that follow the pattern "Error XXX:" where XXX is a 3-digit number. If no valid error number is found, defaults to error code 100. The class prints formatted error messages with a distinctive header and suppresses Python traceback information by setting sys.tracebacklimit = 0. """ def __init__(self, msg): # don't show the error code, lines etc. sys.tracebacklimit = 0 header = "\n\n ========================== CWATM ERROR =============================\n" print(header + msg + "\n") try: errornumber = int(msg[6:9]) except: errornumber = 100 # sys.exit(errornumber) print("CWatM errornumber: " + str(errornumber))
[docs]class CWATMFileError(CWATMError): """ Specialized error handling class for file-related errors. This class extends CWATMError to provide detailed diagnostics for file access issues, including path validation and suggestions for common file problems in CWatM. Parameters ---------- filename : str Full path to the problematic file msg : str, optional Error message string, by default "" sname : str, optional Setting name or context where the error occurred, by default "" Notes ----- Provides enhanced diagnostics by: - Checking if the file exists but has other issues - Verifying if the directory path exists but filename is wrong - Suggesting common file extension alternatives (.nc4, .nc) - Providing context about which settings section caused the error The diagnostic information helps users quickly identify whether the issue is a missing directory, incorrect filename, or file permission problem. """ def __init__(self, filename, msg="", sname=""): # don't show the error code, lines etc. sys.tracebacklimit = 0 path, name = os.path.split(filename) if os.path.exists(filename): text1 = "In \"" + sname + "\"\n" text1 += "filename: "+ filename + " exists, but an error was raised" elif os.path.exists(path): text1 = "In \"" + sname + "\"\n" text1 += "path: "+ path + " exists\nbut filename: "+name+ " does not\n" text1 +="file name extension can be .nc4 or .nc\n" else: text1 = " In \""+ sname +"\"\n" text1 += "searching: \""+filename+"\"" text1 += "\npath: "+ path + " does not exists\n" header = "\n\n ======================== CWATM FILE ERROR ===========================\n" print (header + msg + text1 +"\n") try: errornumber = int(msg[6:9]) except: errornumber = 100 print ("CWatM errornumber: " + str(errornumber))
#sys.exit(errornumber)
[docs]class CWATMDirError(CWATMError): """ Specialized error handling class for directory-related errors. This class extends CWATMError to provide detailed diagnostics for directory access issues, helping users identify problems with output directories, input data directories, and path configuration in settings files. Parameters ---------- filename : str Full path to the problematic directory msg : str, optional Error message string, by default "" sname : str, optional Setting name or context where the error occurred, by default "" Notes ----- Provides enhanced diagnostics by: - Checking if the directory exists but has permission or other issues - Verifying if the parent directory exists but the target subdirectory doesn't - Identifying which settings section contains the problematic directory path - Suggesting potential solutions for common directory problems This is particularly useful for output directory configuration where users may specify non-existent paths or lack write permissions. """ def __init__(self, filename, msg="", sname=""): # don't show the error code, lines etc. sys.tracebacklimit = 0 path, name = os.path.split(filename) if os.path.exists(filename): text1 = "in setting name \"" + sname + "\"\n" text1 += "directory name: "+ filename + " exists, but an error was raised" elif os.path.exists(path): text1 = "in setting name: \"" + sname + "\"\n" text1 += "directory path: "+ path + " exists\nbut: "+name+ " does not\n" else: text1 = " in settings name: \""+ sname +"\"\n" text1 += "searching: \""+filename+"\"" text1 += "\npath: "+ path + " does not exists\n" header = "\n\n ======================== CWATM FILE ERROR ===========================\n" print (header + msg + text1 +"\n") try: errornumber = int(msg[6:9]) except: errornumber = 100 #sys.exit(errornumber) print("CWatM errornumber: " + str(errornumber))
[docs]class CWATMWarning(Warning): """ Warning handling class for non-fatal CWatM issues. This class provides standardized warning messages for situations that don't stop model execution but should be brought to the user's attention. Unlike error classes, warnings don't terminate the program. Parameters ---------- msg : str Warning message to be displayed to the user Notes ----- Warnings are formatted with a distinctive header and temporarily suppress traceback information during initialization. The traceback limit is restored after initialization to maintain normal Python error handling for other issues. Use this class for: - Parameter values outside recommended ranges - Missing optional input data - Deprecated feature usage - Performance-related advisories """ def __init__(self, msg): sys.tracebacklimit = 0 header = "\n========================== CWATM Warning =============================\n" self._msg = header + msg sys.tracebacklimit = 1 def __str__(self): return self._msg
[docs]class CWATMRunInfo(Warning): """ Information display class for CWatM simulation status and settings. This class provides formatted information messages about simulation progress, output locations, and configuration details. Used to communicate important information to users without indicating errors or warnings. Parameters ---------- outputS : list List containing output information, typically [settings_file, output_directory] Returns ------- str Formatted information message with header and simulation details Notes ----- This class is used to provide users with: - Confirmation of simulation settings and output locations - Progress updates during long model runs - Summary information about completed simulations - Configuration validation results The message format is designed to be informative and easy to locate in model output logs. """ def __init__(self, outputS): header = "CWATM Simulation Information and Setting\n" msg = "The simulation output as specified in the settings file: " + str(outputS[0]) + " can be found in "+str(outputS[1])+"\n" self._msg = header + msg def __str__(self): return self._msg