Skip to content

Commit 286e905

Browse files
Replace BaseException with Exception across codebase (#8859)
## Summary Fixes #7401 - Replaced all 17 occurrences of `except BaseException` with `except Exception` across 13 files in `monai/` and `tests/` - Catching `BaseException` inadvertently suppresses `KeyboardInterrupt`, `SystemExit`, and `GeneratorExit`, which should nearly always propagate - `Exception` is the appropriate base class for catchable errors in all these contexts ## Files changed - `monai/__init__.py` - `monai/config/deviceconfig.py` - `monai/utils/tf32.py` - `monai/inferers/inferer.py` - `monai/data/__init__.py` - `monai/apps/auto3dseg/utils.py` - `monai/apps/auto3dseg/ensemble_builder.py` - `monai/apps/auto3dseg/data_analyzer.py` - `monai/apps/detection/metrics/coco.py` - `monai/apps/nnunet/nnunetv2_runner.py` - `tests/test_utils.py` - `tests/networks/nets/test_resnet.py` - `tests/apps/detection/networks/test_retinanet.py` ## Test plan - [x] All existing unit tests should pass without modification (this is a strict narrowing of catch scope) - [ ] Verify `KeyboardInterrupt` (Ctrl+C) is no longer silently swallowed during long-running operations Signed-off-by: Oleksandr Sanin <alexaaander.sanin@gmail.com> --------- Signed-off-by: Oleksandr Sanin <alexaaander.sanin@gmail.com> Signed-off-by: Oleksandr Yizchak Sanin <alexaaander.sanin@gmail.com>
1 parent ef2acfb commit 286e905

13 files changed

Lines changed: 17 additions & 17 deletions

File tree

monai/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def filter(self, record):
131131
# workaround related to https://github.com/Project-MONAI/MONAI/issues/7575
132132
if hasattr(torch.cuda.device_count, "cache_clear"):
133133
torch.cuda.device_count.cache_clear()
134-
except BaseException:
134+
except Exception:
135135
from .utils.misc import MONAIEnvVars
136136

137137
if MONAIEnvVars.debug():

monai/apps/auto3dseg/data_analyzer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ def _get_all_case_stats(
341341
_label_argmax = True # track if label is argmaxed
342342
batch_data[self.label_key] = label.to(device)
343343
d = summarizer(batch_data)
344-
except BaseException as err:
344+
except Exception as err:
345345
if "image_meta_dict" in batch_data.keys():
346346
filename = batch_data["image_meta_dict"][ImageMetaKey.FILENAME_OR_OBJ]
347347
else:
@@ -357,7 +357,7 @@ def _get_all_case_stats(
357357
label = torch.argmax(label, dim=0) if label.shape[0] > 1 else label[0]
358358
batch_data[self.label_key] = label.to("cpu")
359359
d = summarizer(batch_data)
360-
except BaseException as err:
360+
except Exception as err:
361361
logger.info(f"Unable to process data {filename} on {device}. {err}")
362362
continue
363363
else:

monai/apps/auto3dseg/ensemble_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ def __call__(self, pred_param: dict | None = None) -> list:
216216
if "image_save_func" in param:
217217
try:
218218
ensemble_preds = self.ensemble_pred(preds, sigmoid=sigmoid)
219-
except BaseException:
219+
except Exception:
220220
ensemble_preds = self.ensemble_pred([_.to("cpu") for _ in preds], sigmoid=sigmoid)
221221
res = img_saver(ensemble_preds)
222222
# res is the path to the saved results

monai/apps/auto3dseg/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ def import_bundle_algo_history(
5959
if best_metric is None:
6060
try:
6161
best_metric = algo.get_score()
62-
except BaseException:
62+
except Exception:
6363
pass
6464

6565
is_trained = best_metric is not None

monai/apps/detection/metrics/coco.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ def _compute_stats_single_threshold(
541541
for save_idx, array_index in enumerate(inds):
542542
precision[save_idx] = pr[array_index]
543543
th_scores[save_idx] = dt_scores_sorted[array_index]
544-
except BaseException:
544+
except Exception:
545545
pass
546546

547547
return recall, np.array(precision), np.array(th_scores)

monai/apps/nnunet/nnunetv2_runner.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ def __init__(
200200
from nnunetv2.utilities.dataset_name_id_conversion import maybe_convert_to_dataset_name
201201

202202
self.dataset_name = maybe_convert_to_dataset_name(int(self.dataset_name_or_id))
203-
except BaseException:
203+
except Exception:
204204
logger.warning(
205205
f"Dataset with name/ID: {self.dataset_name_or_id} cannot be found in the record. "
206206
"Please ignore the message above if you are running the pipeline from a fresh start. "
@@ -278,7 +278,7 @@ def convert_dataset(self):
278278
num_input_channels=num_input_channels,
279279
output_datafolder=raw_data_foldername,
280280
)
281-
except BaseException as err:
281+
except Exception as err:
282282
logger.warning(f"Input config may be incorrect. Detail info: error/exception message is:\n {err}")
283283
return
284284

monai/config/deviceconfig.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ def print_config(file=sys.stdout):
120120
def _dict_append(in_dict, key, fn):
121121
try:
122122
in_dict[key] = fn() if callable(fn) else fn
123-
except BaseException:
123+
except Exception:
124124
in_dict[key] = "UNKNOWN for given OS"
125125

126126

monai/data/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
from .wsi_datasets import MaskedPatchWSIDataset, PatchWSIDataset, SlidingPatchWSIDataset
119119
from .wsi_reader import BaseWSIReader, CuCIMWSIReader, OpenSlideWSIReader, TiffFileWSIReader, WSIReader
120120

121-
with contextlib.suppress(BaseException):
121+
with contextlib.suppress(Exception):
122122
from multiprocessing.reduction import ForkingPickler
123123

124124
def _rebuild_meta(cls, storage, dtype, metadata):

monai/inferers/inferer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ def __init__(
545545
)
546546
if cache_roi_weight_map and self.roi_weight_map is None:
547547
warnings.warn("cache_roi_weight_map=True, but cache is not created. (dynamic roi_size?)")
548-
except BaseException as e:
548+
except Exception as e:
549549
raise RuntimeError(
550550
f"roi size {self.roi_size}, mode={mode}, sigma_scale={sigma_scale}, device={device}\n"
551551
"Seems to be OOM. Please try smaller patch size or mode='constant' instead of mode='gaussian'."

monai/utils/tf32.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def has_ampere_or_later() -> bool:
4141
major, _ = pynvml.nvmlDeviceGetCudaComputeCapability(handle)
4242
if major >= 8:
4343
return True
44-
except BaseException:
44+
except Exception:
4545
pass
4646
finally:
4747
pynvml.nvmlShutdown()
@@ -71,7 +71,7 @@ def detect_default_tf32() -> bool:
7171
may_enable_tf32 = True
7272

7373
return may_enable_tf32
74-
except BaseException:
74+
except Exception:
7575
from monai.utils.misc import MONAIEnvVars
7676

7777
if MONAIEnvVars.debug():

0 commit comments

Comments
 (0)