Repository: pydicom/pydicom

Issue:
Dataset.to_json_dict can still generate exceptions when suppress_invalid_tags=True
**Describe the bug**
I'm using `Dataset.to_json_dict(suppress_invalid_tags=True)` and can live with losing invalid tags.  Unfortunately, I can still trigger an exception with something like  `2.0` in an `IS` field.

**Expected behavior**
to_json_dict shouldn't throw an error about an invalid tag when `suppress_invalid_tags` is enabled.

My thought was simply to move the `data_element = self[key]` into the try/catch block that's right after it.

**Steps To Reproduce**

Traceback:
```
  File "dicom.py", line 143, in create_dict
    json_ds = ds.to_json_dict(suppress_invalid_tags=True)
  File "/usr/lib/python3/dist-packages/pydicom/dataset.py", line 2495, in to_json_dict
    data_element = self[key]
  File "/usr/lib/python3/dist-packages/pydicom/dataset.py", line 939, in __getitem__
    self[tag] = DataElement_from_raw(elem, character_set, self)
  File "/usr/lib/python3/dist-packages/pydicom/dataelem.py", line 859, in DataElement_from_raw
    value = convert_value(vr, raw, encoding)
  File "/usr/lib/python3/dist-packages/pydicom/values.py", line 771, in convert_value
    return converter(byte_string, is_little_endian, num_format)
  File "/usr/lib/python3/dist-packages/pydicom/values.py", line 348, in convert_IS_string
    return MultiString(num_string, valtype=pydicom.valuerep.IS)
  File "/usr/lib/python3/dist-packages/pydicom/valuerep.py", line 1213, in MultiString
    return valtype(splitup[0])
  File "/usr/lib/python3/dist-packages/pydicom/valuerep.py", line 1131, in __new__
    raise TypeError("Could not convert value to integer without loss")
TypeError: Could not convert value to integer without loss
```

**Your environment**
python 3.7, pydicom 2.3



Discussion:
codecov[bot]: # [Codecov](https://codecov.io/gh/pydicom/pydicom/pull/1694?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) Report
> Merging [#1694](https://codecov.io/gh/pydicom/pydicom/pull/1694?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) (d4335b7) into [master](https://codecov.io/gh/pydicom/pydicom/commit/f8cf45b6c121e5a4bf4a43f71aba3bc64af3db9c?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) (f8cf45b) will **decrease** coverage by `9.34%`.
> The diff coverage is `100.00%`.

```diff
@@            Coverage Diff             @@
##           master    #1694      +/-   ##
==========================================
- Coverage   97.58%   88.24%   -9.35%     
==========================================
  Files          66       66              
  Lines       10737    10504     -233     
==========================================
- Hits        10478     9269    -1209     
- Misses        259     1235     +976     
```


| [Impacted Files](https://codecov.io/gh/pydicom/pydicom/pull/1694?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) | Coverage Δ | |
|---|---|---|
| [pydicom/dataset.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9kYXRhc2V0LnB5) | `94.36% <100.00%> (-4.70%)` | :arrow_down: |
| [pydicom/pixel\_data\_handlers/util.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9waXhlbF9kYXRhX2hhbmRsZXJzL3V0aWwucHk=) | `17.93% <0.00%> (-82.07%)` | :arrow_down: |
| [pydicom/waveforms/numpy\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS93YXZlZm9ybXMvbnVtcHlfaGFuZGxlci5weQ==) | `20.31% <0.00%> (-79.69%)` | :arrow_down: |
| [pydicom/encoders/gdcm.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9lbmNvZGVycy9nZGNtLnB5) | `20.96% <0.00%> (-75.81%)` | :arrow_down: |
| [pydicom/pixel\_data\_handlers/numpy\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9waXhlbF9kYXRhX2hhbmRsZXJzL251bXB5X2hhbmRsZXIucHk=) | `27.14% <0.00%> (-72.86%)` | :arrow_down: |
| [pydicom/pixel\_data\_handlers/gdcm\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9waXhlbF9kYXRhX2hhbmRsZXJzL2dkY21faGFuZGxlci5weQ==) | `26.22% <0.00%> (-66.46%)` | :arrow_down: |
| [pydicom/overlays/numpy\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9vdmVybGF5cy9udW1weV9oYW5kbGVyLnB5) | `35.18% <0.00%> (-64.82%)` | :arrow_down: |
| [pydicom/pixel\_data\_handlers/pillow\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9waXhlbF9kYXRhX2hhbmRsZXJzL3BpbGxvd19oYW5kbGVyLnB5) | `31.73% <0.00%> (-64.43%)` | :arrow_down: |
| [pydicom/pixel\_data\_handlers/rle\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9waXhlbF9kYXRhX2hhbmRsZXJzL3JsZV9oYW5kbGVyLnB5) | `36.97% <0.00%> (-63.03%)` | :arrow_down: |
| [pydicom/pixel\_data\_handlers/pylibjpeg\_handler.py](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom#diff-cHlkaWNvbS9waXhlbF9kYXRhX2hhbmRsZXJzL3B5bGlianBlZ19oYW5kbGVyLnB5) | `40.74% <0.00%> (-57.41%)` | :arrow_down: |
| ... and [16 more](https://codecov.io/gh/pydicom/pydicom/pull/1694/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom) | |

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=pydicom)


Patch:
diff --git a/doc/release_notes/v2.4.0.rst b/doc/release_notes/v2.4.0.rst
index b11c4d0ec..4bbf848b0 100644
--- a/doc/release_notes/v2.4.0.rst
+++ b/doc/release_notes/v2.4.0.rst
@@ -19,3 +19,6 @@ Fixes
 * Fixed extremely long BytesLengthException error messages (:pr:`1683`)
 * In codify, ensure unique variable names for DICOM keywords repeated
   in sequences, and handle unicode characters correctly (:issue:`1670`)
+* Fixed handling of some invalid values in
+  :meth:`~pydicom.dataset.Dataset.to_json_dict` if `suppress_invalid_tags` is
+  set to `True` (:issue:`1693`)
diff --git a/pydicom/dataset.py b/pydicom/dataset.py
index e32315011..a6f887966 100644
--- a/pydicom/dataset.py
+++ b/pydicom/dataset.py
@@ -2492,8 +2492,8 @@ class Dataset:
         json_dataset = {}
         for key in self.keys():
             json_key = '{:08X}'.format(key)
-            data_element = self[key]
             try:
+                data_element = self[key]
                 json_dataset[json_key] = data_element.to_json_dict(
                     bulk_data_element_handler=bulk_data_element_handler,
                     bulk_data_threshold=bulk_data_threshold


Test patch:
diff --git a/pydicom/tests/test_json.py b/pydicom/tests/test_json.py
index 0b2cbeff6..5eed9a15a 100644
--- a/pydicom/tests/test_json.py
+++ b/pydicom/tests/test_json.py
@@ -7,7 +7,7 @@ import pytest
 
 from pydicom import dcmread
 from pydicom.data import get_testdata_file
-from pydicom.dataelem import DataElement
+from pydicom.dataelem import DataElement, RawDataElement
 from pydicom.dataset import Dataset
 from pydicom.tag import Tag, BaseTag
 from pydicom.valuerep import PersonName
@@ -284,7 +284,23 @@ class TestDataSetToJson:
 
         ds_json = ds.to_json_dict(suppress_invalid_tags=True)
 
-        assert ds_json.get("00100010") is None
+        assert "00100010" not in ds_json
+
+    def test_suppress_invalid_tags_with_failed_dataelement(self):
+        """Test tags that raise exceptions don't if suppress_invalid_tags True.
+        """
+        ds = Dataset()
+        # we have to add a RawDataElement as creating a DataElement would
+        # already raise an exception
+        ds[0x00082128] = RawDataElement(
+            Tag(0x00082128), 'IS', 4, b'5.25', 0, True, True)
+
+        with pytest.raises(TypeError):
+            ds.to_json_dict()
+
+        ds_json = ds.to_json_dict(suppress_invalid_tags=True)
+
+        assert "00082128" not in ds_json
 
 
 class TestSequence: