-
Notifications
You must be signed in to change notification settings - Fork 210
Exceptions #381
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Exceptions #381
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
21a8d14
Update epanet exceptions
dbhart 8fa41a3
Update to have cleaner exceptions during IO
dbhart ae27699
Update to exception documentation
dbhart 2090215
Update documentation for EN errors
dbhart bbbd46d
Merge branch 'USEPA:main' into exceptions
dbhart f223586
Update to correct the exceptions listings
dbhart 4171489
Fix the imports in wntr-epanet-init
dbhart 2fb49db
Documentation on EPANET exceptions
dbhart cc4587e
Spelling errors
dbhart a3594a3
Updates to address comments in PR. Tests forthcoming
dbhart 6504ad0
Merge branch 'USEPA:main' into exceptions
dbhart a4557e7
Merge branch 'main' of github.com:USEPA/WNTR into USEPA-main
dbhart fb717d2
Merge branch 'USEPA-main' into exceptions
dbhart 900561a
Added the tests for exceptions
dbhart 1474f42
Documentation updates for exceptions.
dbhart bd5aca1
Fix to a documentation error that slipped in
dbhart ea9b48a
Merge branch 'USEPA:main' into exceptions
dbhart 48f5565
Merge branch 'USEPA:main' into exceptions
dbhart f3588ff
Updates to make exceptions tested in io.py
dbhart db2a2d6
Get rid of spurrious documentation. Ready for PR
dbhart 806b04e
Update userguide
dbhart File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,181 @@ | ||
# coding: utf-8 | ||
"""Exceptions for EPANET toolkit and IO operations.""" | ||
|
||
from typing import List | ||
|
||
EN_ERROR_CODES = { | ||
# Runtime errors | ||
1: "At %s, system hydraulically unbalanced - convergence to a hydraulic solution was not achieved in the allowed number of trials", | ||
2: "At %s, system may be hydraulically unstable - hydraulic convergence was only achieved after the status of all links was held fixed", | ||
3: "At %s, system disconnected - one or more nodes with positive demands were disconnected for all supply sources", | ||
4: "At %s, pumps cannot deliver enough flow or head - one or more pumps were forced to either shut down (due to insufficient head) or operate beyond the maximum rated flow", | ||
5: "At %s, valves cannot deliver enough flow - one or more flow control valves could not deliver the required flow even when fully open", | ||
6: "At %s, system has negative pressures - negative pressures occurred at one or more junctions with positive demand", | ||
101: "insufficient memory available", | ||
102: "no network data available", | ||
103: "hydraulics not initialized", | ||
104: "no hydraulics for water quality analysis", | ||
105: "water quality not initialized", | ||
106: "no results saved to report on", | ||
107: "hydraulics supplied from external file", | ||
108: "cannot use external file while hydraulics solver is active", | ||
109: "cannot change time parameter when solver is active", | ||
110: "cannot solve network hydraulic equations", | ||
120: "cannot solve water quality transport equations", | ||
# Apply only to an input file | ||
200: "one or more errors in input file %s", | ||
201: "syntax error (%s)", | ||
# Apply to both IO file and API functions | ||
202: "illegal numeric value, %s", | ||
203: "undefined node, %s", | ||
204: "undefined link, %s", | ||
205: "undefined time pattern, %s", | ||
206: "undefined curve, %s", | ||
207: "attempt to control a CV/GPV link", | ||
208: "illegal PDA pressure limits", | ||
209: "illegal node property value", | ||
211: "illegal link property value", | ||
212: "undefined trace node", | ||
213: "invalid option value %s", | ||
214: "too many characters in input line", | ||
215: "duplicate ID label", | ||
216: "reference to undefined pump", | ||
217: "pump has no head curve or power defined", | ||
219: "illegal valve connection to tank node", | ||
220: "illegal valve connection to another valve", | ||
221: "misplaced rule clause in rule-based control", | ||
222: "link assigned same start and end nodes", | ||
# Network consistency | ||
223: "not enough nodes in network", | ||
224: "no tanks or reservoirs in network", | ||
225: "invalid lower/upper levels for tank", | ||
226: "no head curve or power rating for pump", | ||
227: "invalid head curve for pump", | ||
230: "nonincreasing x-values for curve", | ||
233: "network has unconnected node", | ||
234: "network has an unconnected node with ID %s", | ||
# API functions only | ||
240: "nonexistent water quality source", | ||
241: "nonexistent control", | ||
250: "invalid format (e.g. too long an ID name)", | ||
251: "invalid parameter code", | ||
252: "invalid ID name", | ||
253: "nonexistent demand category", | ||
254: "node with no coordinates", | ||
255: "invalid link vertex", | ||
257: "nonexistent rule", | ||
258: "nonexistent rule clause", | ||
259: "attempt to delete a node that still has links connected to it", | ||
260: "attempt to delete node assigned as a Trace Node", | ||
261: "attempt to delete a node or link contained in a control", | ||
262: "attempt to modify network structure while a solver is open", | ||
263: "node is not a tank", | ||
# File errors | ||
301: "identical file names used for different types of files", | ||
302: "cannot open input file %s", | ||
303: "cannot open report file %s", | ||
304: "cannot open binary output file %s", | ||
305: "cannot open hydraulics file %s", | ||
306: "hydraulics file does not match network data", | ||
307: "cannot read hydraulics file %s", | ||
308: "cannot save results to binary file %s", | ||
309: "cannot save results to report file %s", | ||
} | ||
"""A dictionary of the error codes and their meanings from the EPANET toolkit. | ||
|
||
:meta hide-value: | ||
""" | ||
|
||
|
||
class EpanetException(Exception): | ||
|
||
def __init__(self, code: int, *args: List[object], line_num=None, line=None) -> None: | ||
"""An Exception class for EPANET Toolkit and IO exceptions. | ||
|
||
Parameters | ||
---------- | ||
code : int | ||
The EPANET error code | ||
args : additional non-keyword arguments, optional | ||
If there is a string-format within the error code's text, these will be used to | ||
replace the format, otherwise they will be output at the end of the Exception message. | ||
line_num : int, optional | ||
The line number, if reading an INP file, by default None | ||
line : str, optional | ||
The contents of the line, by default None | ||
""" | ||
msg = EN_ERROR_CODES.get(code, "unknown error") | ||
if args is not None: | ||
args = [*args] | ||
if r"%" in msg and len(args) > 0: | ||
msg = msg % repr(args.pop(0)) | ||
if len(args) > 0: | ||
msg = msg + " " + repr(args) | ||
if line_num: | ||
msg = msg + ", at line {}".format(line_num) | ||
if line: | ||
msg = msg + ":\n " + str(line) | ||
msg = "(Error {}) ".format(code) + msg | ||
super().__init__(msg) | ||
|
||
|
||
class ENSyntaxError(EpanetException, SyntaxError): | ||
def __init__(self, code, *args, line_num=None, line=None) -> None: | ||
"""An EPANET exception class that also subclasses SyntaxError | ||
|
||
Parameters | ||
---------- | ||
code : int | ||
The EPANET error code | ||
args : additional non-keyword arguments, optional | ||
If there is a string-format within the error code's text, these will be used to | ||
replace the format, otherwise they will be output at the end of the Exception message. | ||
line_num : int, optional | ||
The line number, if reading an INP file, by default None | ||
line : str, optional | ||
The contents of the line, by default None | ||
""" | ||
super().__init__(code, *args, line_num=line_num, line=line) | ||
|
||
|
||
class ENKeyError(EpanetException, KeyError): | ||
def __init__(self, code, name, *args, line_num=None, line=None) -> None: | ||
"""An EPANET exception class that also subclasses KeyError. | ||
|
||
Parameters | ||
---------- | ||
code : int | ||
The EPANET error code | ||
name : str | ||
The key/name/id that is missing | ||
args : additional non-keyword arguments, optional | ||
If there is a string-format within the error code's text, these will be used to | ||
replace the format, otherwise they will be output at the end of the Exception message. | ||
line_num : int, optional | ||
The line number, if reading an INP file, by default None | ||
line : str, optional | ||
The contents of the line, by default None | ||
""" | ||
|
||
super().__init__(code, name, *args, line_num=line_num, line=line) | ||
|
||
|
||
class ENValueError(EpanetException, ValueError): | ||
def __init__(self, code, value, *args, line_num=None, line=None) -> None: | ||
"""An EPANET exception class that also subclasses ValueError | ||
|
||
Parameters | ||
---------- | ||
code : int | ||
The EPANET error code | ||
value : Any | ||
The value that is invalid | ||
args : additional non-keyword arguments, optional | ||
If there is a string-format within the error code's text, these will be used to | ||
replace the format, otherwise they will be output at the end of the Exception message. | ||
line_num : int, optional | ||
The line number, if reading an INP file, by default None | ||
line : str, optional | ||
The contents of the line, by default None | ||
""" | ||
super().__init__(code, value, *args, line_num=line_num, line=line) | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.