Skip to content

Commit 73035a3

Browse files
authored
Update error message (#292)
* Update error message * Remove SystemExit * News * Refactor default labels from [r],[gr]->[x],[fx] when saving (#294) * Remove PDF language when saving * news * Fixed tests for squeeze morph warnings (#295) * Robust warning handling * News * Nonews
1 parent 8f9e0ff commit 73035a3

File tree

4 files changed

+142
-104
lines changed

4 files changed

+142
-104
lines changed

news/error-message.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
**Added:**
2+
3+
* <news item>
4+
5+
**Changed:**
6+
7+
* Program no longer gives SystemExit. Proper errors are assigned to each case.
8+
9+
**Deprecated:**
10+
11+
* <news item>
12+
13+
**Removed:**
14+
15+
* <news item>
16+
17+
**Fixed:**
18+
19+
* <news item>
20+
21+
**Security:**
22+
23+
* <news item>

src/diffpy/morph/morphapp.py

Lines changed: 79 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ class CustomParser(optparse.OptionParser):
4141
def __init__(self, *args, **kwargs):
4242
super(CustomParser, self).__init__(*args, **kwargs)
4343

44-
def custom_error(self, msg):
45-
"""custom_error(msg : string)
44+
def morph_error(self, msg, error):
45+
"""morph_error(msg : string)
4646
4747
Print a message incorporating 'msg' to stderr and exit. Does
4848
not print usage.
4949
"""
50-
self.exit(2, "%s: error: %s\n" % (self.get_prog_name(), msg))
50+
raise error(f"{self.get_prog_name()}: {msg}")
5151

5252
parser = CustomParser(
5353
usage="\n".join(
@@ -507,14 +507,17 @@ def single_morph(
507507
parser, opts, pargs, stdout_flag=True, python_wrap=False, pymorphs=None
508508
):
509509
if len(pargs) < 2:
510-
parser.error("You must supply MORPHFILE and TARGETFILE.")
510+
parser.morph_error(
511+
"You must supply MORPHFILE and TARGETFILE.", TypeError
512+
)
511513
elif len(pargs) > 2 and not python_wrap:
512-
parser.error(
514+
parser.morph_error(
513515
"Too many arguments. Make sure you only supply "
514-
"MORPHFILE and TARGETFILE."
516+
"MORPHFILE and TARGETFILE.",
517+
TypeError,
515518
)
516519
elif not (len(pargs) == 2 or len(pargs) == 6) and python_wrap:
517-
parser.error("Python wrapper error.")
520+
parser.morph_error("Python wrapper error.", RuntimeError)
518521

519522
# Get the PDFs
520523
# If we get from python, we may wrap, which has input size 4
@@ -528,9 +531,9 @@ def single_morph(
528531
x_target, y_target = getPDFFromFile(pargs[1])
529532

530533
if y_morph is None:
531-
parser.error(f"No data table found in: {pargs[0]}.")
534+
parser.morph_error(f"No data table found in: {pargs[0]}.", ValueError)
532535
if y_target is None:
533-
parser.error(f"No data table found in: {pargs[1]}.")
536+
parser.morph_error(f"No data table found in: {pargs[1]}.", ValueError)
534537

535538
# Get tolerance
536539
tolerance = 1e-08
@@ -549,8 +552,8 @@ def single_morph(
549552
and opts.xmax is not None
550553
and opts.xmax <= opts.xmin
551554
):
552-
e = "xmin must be less than xmax"
553-
parser.custom_error(e)
555+
emsg = "xmin must be less than xmax"
556+
parser.morph_error(emsg, ValueError)
554557

555558
# Set up the morphs
556559
chain = morphs.MorphChain(config)
@@ -607,7 +610,9 @@ def single_morph(
607610
squeeze_dict_in.update({f"a{idx}": float(coeff)})
608611
idx += 1
609612
except ValueError:
610-
parser.error(f"{coeff} could not be converted to float.")
613+
parser.morph_error(
614+
f"{coeff} could not be converted to float.", ValueError
615+
)
611616
squeeze_poly_deg = len(squeeze_dict_in.keys())
612617
squeeze_morph = morphs.MorphSqueeze()
613618
chain.append(squeeze_morph)
@@ -727,7 +732,7 @@ def single_morph(
727732
# Adjust all parameters
728733
refiner.refine(*refpars)
729734
except ValueError as e:
730-
parser.custom_error(str(e))
735+
parser.morph_error(str(e), ValueError)
731736
# Smear is not being refined, but baselineslope needs to refined to apply
732737
# smear
733738
# Note that baselineslope is only added to the refine list if smear is
@@ -738,7 +743,7 @@ def single_morph(
738743
"baselineslope", baselineslope=config["baselineslope"]
739744
)
740745
except ValueError as e:
741-
parser.custom_error(str(e))
746+
parser.morph_error(str(e), ValueError)
742747
else:
743748
chain(x_morph, y_morph, x_target, y_target)
744749

@@ -827,9 +832,9 @@ def single_morph(
827832
stdout_flag=stdout_flag,
828833
)
829834

830-
except (FileNotFoundError, RuntimeError):
835+
except (FileNotFoundError, RuntimeError) as e:
831836
save_fail_message = "Unable to save to designated location."
832-
parser.custom_error(save_fail_message)
837+
parser.morph_error(save_fail_message, type(e))
833838

834839
if opts.plot:
835840
pairlist = [chain.xy_target_out, chain.xy_morph_out]
@@ -871,25 +876,29 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
871876
# Custom error messages since usage is distinct when --multiple tag is
872877
# applied
873878
if len(pargs) < 2:
874-
parser.custom_error(
879+
parser.morph_error(
875880
"You must supply a FILE and DIRECTORY. "
876-
"See --multiple-targets under --help for usage."
881+
"See --multiple-targets under --help for usage.",
882+
TypeError,
877883
)
878884
elif len(pargs) > 2:
879-
parser.custom_error(
880-
"Too many arguments. You must only supply a FILE and a DIRECTORY."
885+
parser.morph_error(
886+
"Too many arguments. You must only supply a FILE and a DIRECTORY.",
887+
TypeError,
881888
)
882889

883890
# Parse paths
884891
morph_file = Path(pargs[0])
885892
if not morph_file.is_file():
886-
parser.custom_error(
887-
f"{morph_file} is not a file. Go to --help for usage."
893+
parser.morph_error(
894+
f"{morph_file} is not a file. Go to --help for usage.",
895+
FileNotFoundError,
888896
)
889897
target_directory = Path(pargs[1])
890898
if not target_directory.is_dir():
891-
parser.custom_error(
892-
f"{target_directory} is not a directory. Go to --help for usage."
899+
parser.morph_error(
900+
f"{target_directory} is not a directory. Go to --help for usage.",
901+
NotADirectoryError,
893902
)
894903

895904
# Get list of files from target directory
@@ -926,12 +935,14 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
926935
)
927936
except KeyError:
928937
if opts.serfile is not None:
929-
parser.custom_error(
930-
"The requested field was not found in the metadata file."
938+
parser.morph_error(
939+
"The requested field was not found in the metadata file.",
940+
KeyError,
931941
)
932942
else:
933-
parser.custom_error(
934-
"The requested field is missing from a file header."
943+
parser.morph_error(
944+
"The requested field is missing from a file header.",
945+
KeyError,
935946
)
936947
else:
937948
# Default is alphabetical sort
@@ -953,9 +964,9 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
953964
save_morphs_here = io.create_morphs_directory(save_directory)
954965

955966
# Could not create directory or find names to save morphs as
956-
except (FileNotFoundError, RuntimeError):
967+
except (FileNotFoundError, RuntimeError) as e:
957968
save_fail_message = "\nUnable to create directory"
958-
parser.custom_error(save_fail_message)
969+
parser.morph_error(save_fail_message, type(e))
959970

960971
try:
961972
save_names = io.get_multisave_names(
@@ -964,7 +975,7 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
964975
# Could not create directory or find names to save morphs as
965976
except FileNotFoundError:
966977
save_fail_message = "\nUnable to read from save names file"
967-
parser.custom_error(save_fail_message)
978+
parser.morph_error(save_fail_message, FileNotFoundError)
968979

969980
# Morph morph_file against all other files in target_directory
970981
morph_results = {}
@@ -1013,9 +1024,9 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
10131024
verbose=opts.verbose,
10141025
stdout_flag=stdout_flag,
10151026
)
1016-
except (FileNotFoundError, RuntimeError):
1027+
except (FileNotFoundError, RuntimeError) as e:
10171028
save_fail_message = "Unable to save summary to directory."
1018-
parser.custom_error(save_fail_message)
1029+
parser.morph_error(save_fail_message, type(e))
10191030

10201031
# Plot the values of some parameter for each target if requested
10211032
if plot_opt:
@@ -1032,8 +1043,9 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
10321043
# Not an available parameter to plot or no values found for the
10331044
# parameter
10341045
if param_list is None:
1035-
parser.custom_error(
1036-
"Cannot find specified plot parameter. No plot shown."
1046+
parser.morph_error(
1047+
"Cannot find specified plot parameter. No plot shown.",
1048+
KeyError,
10371049
)
10381050
else:
10391051
try:
@@ -1045,9 +1057,10 @@ def multiple_targets(parser, opts, pargs, stdout_flag=True, python_wrap=False):
10451057
# i.e. --smear is not selected as an option, but smear is the
10461058
# plotting parameter
10471059
except ValueError:
1048-
parser.custom_error(
1060+
parser.morph_error(
10491061
"The plot parameter is missing values for at least one "
1050-
"morph and target pair. No plot shown."
1062+
"morph and target pair. No plot shown.",
1063+
ValueError,
10511064
)
10521065

10531066
return morph_results
@@ -1057,25 +1070,29 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
10571070
# Custom error messages since usage is distinct when --multiple tag is
10581071
# applied
10591072
if len(pargs) < 2:
1060-
parser.custom_error(
1073+
parser.morph_error(
10611074
"You must supply a DIRECTORY and FILE. "
1062-
"See --multiple-morphs under --help for usage."
1075+
"See --multiple-morphs under --help for usage.",
1076+
TypeError,
10631077
)
10641078
elif len(pargs) > 2:
1065-
parser.custom_error(
1066-
"Too many arguments. You must only supply a DIRECTORY and FILE."
1079+
parser.morph_error(
1080+
"Too many arguments. You must only supply a DIRECTORY and FILE.",
1081+
TypeError,
10671082
)
10681083

10691084
# Parse paths
10701085
target_file = Path(pargs[1])
10711086
if not target_file.is_file():
1072-
parser.custom_error(
1073-
f"{target_file} is not a file. Go to --help for usage."
1087+
parser.morph_error(
1088+
f"{target_file} is not a file. Go to --help for usage.",
1089+
FileNotFoundError,
10741090
)
10751091
morph_directory = Path(pargs[0])
10761092
if not morph_directory.is_dir():
1077-
parser.custom_error(
1078-
f"{morph_directory} is not a directory. Go to --help for usage."
1093+
parser.morph_error(
1094+
f"{morph_directory} is not a directory. Go to --help for usage.",
1095+
NotADirectoryError,
10791096
)
10801097

10811098
# Get list of files from morph directory
@@ -1112,12 +1129,14 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
11121129
)
11131130
except KeyError:
11141131
if opts.serfile is not None:
1115-
parser.custom_error(
1116-
"The requested field was not found in the metadata file."
1132+
parser.morph_error(
1133+
"The requested field was not found in the metadata file.",
1134+
KeyError,
11171135
)
11181136
else:
1119-
parser.custom_error(
1120-
"The requested field is missing from a PDF file header."
1137+
parser.morph_error(
1138+
"The requested field is missing from a PDF file header.",
1139+
KeyError,
11211140
)
11221141
else:
11231142
# Default is alphabetical sort
@@ -1139,9 +1158,9 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
11391158
save_morphs_here = io.create_morphs_directory(save_directory)
11401159

11411160
# Could not create directory or find names to save morphs as
1142-
except (FileNotFoundError, RuntimeError):
1161+
except (FileNotFoundError, RuntimeError) as e:
11431162
save_fail_message = "\nUnable to create directory"
1144-
parser.custom_error(save_fail_message)
1163+
parser.morph_error(save_fail_message, type(e))
11451164

11461165
try:
11471166
save_names = io.get_multisave_names(
@@ -1150,7 +1169,7 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
11501169
# Could not create directory or find names to save morphs as
11511170
except FileNotFoundError:
11521171
save_fail_message = "\nUnable to read from save names file"
1153-
parser.custom_error(save_fail_message)
1172+
parser.morph_error(save_fail_message, FileNotFoundError)
11541173

11551174
# Morph morph_file against all other files in target_directory
11561175
morph_results = {}
@@ -1200,9 +1219,9 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
12001219
stdout_flag=stdout_flag,
12011220
mm=True,
12021221
)
1203-
except (FileNotFoundError, RuntimeError):
1222+
except (FileNotFoundError, RuntimeError) as e:
12041223
save_fail_message = "Unable to save summary to directory."
1205-
parser.custom_error(save_fail_message)
1224+
parser.morph_error(save_fail_message, type(e))
12061225

12071226
# Plot the values of some parameter for each target if requested
12081227
if plot_opt:
@@ -1219,8 +1238,9 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
12191238
# Not an available parameter to plot or no values found for the
12201239
# parameter
12211240
if param_list is None:
1222-
parser.custom_error(
1223-
"Cannot find specified plot parameter. No plot shown."
1241+
parser.morph_error(
1242+
"Cannot find specified plot parameter. No plot shown.",
1243+
KeyError,
12241244
)
12251245
else:
12261246
try:
@@ -1232,9 +1252,10 @@ def multiple_morphs(parser, opts, pargs, stdout_flag=True, python_wrap=False):
12321252
# i.e. --smear is not selected as an option, but smear is the
12331253
# plotting parameter
12341254
except ValueError:
1235-
parser.custom_error(
1255+
parser.morph_error(
12361256
"The plot parameter is missing values for at least one "
1237-
"morph and target pair. No plot shown."
1257+
"morph and target pair. No plot shown.",
1258+
ValueError,
12381259
)
12391260

12401261
return morph_results

0 commit comments

Comments
 (0)