diff --git a/omegaconf/_utils.py b/omegaconf/_utils.py
index 5879d6d..b42271e 100644
--- a/omegaconf/_utils.py
+++ b/omegaconf/_utils.py
@@ -1,3 +1,4 @@
+import copy
 import os
 import re
 import string
@@ -438,6 +439,23 @@ def format_and_raise(
     from omegaconf import OmegaConf
     from omegaconf.base import Node
 
+    def raise_(ex: Exception, cause: Exception) -> None:
+        # Set the environment variable OC_CAUSE=1 to get a stacktrace that includes the
+        # causing exception.
+        full_backtrace = "OC_CAUSE" in os.environ and os.environ["OC_CAUSE"] == "1"
+        if full_backtrace:
+            ex.__cause__ = cause
+        else:
+            ex.__cause__ = None
+        raise ex
+
+    if isinstance(cause, OmegaConfBaseException) and cause._initialized:
+        ex = cause
+        if type_override is not None:
+            ex = type_override(str(cause))
+            ex.__dict__ = copy.deepcopy(cause.__dict__)
+        raise_(ex, cause)
+
     object_type: Optional[Type[Any]]
     object_type_str: Optional[str] = None
     ref_type: Optional[Type[Any]]
@@ -497,25 +515,18 @@ def format_and_raise(
     ex = exception_type(f"{message}")
     if issubclass(exception_type, OmegaConfBaseException):
         ex._initialized = True
+        ex.msg = message
         ex.parent_node = node
         ex.child_node = child_node
         ex.key = key
         ex.full_key = full_key
         ex.value = value
-        ex.msg = msg
         ex.object_type = object_type
         ex.object_type_str = object_type_str
         ex.ref_type = ref_type
         ex.ref_type_str = ref_type_str
 
-    # Set the environment variable OC_CAUSE=1 to get a stacktrace that includes the
-    # causing exception.
-    full_backtrace = "OC_CAUSE" in os.environ and os.environ["OC_CAUSE"] == "1"
-    if full_backtrace:
-        ex.__cause__ = cause
-    else:
-        ex.__cause__ = None
-    raise ex
+    raise_(ex, cause)
 
 
 def type_str(t: Any) -> str:
diff --git a/omegaconf/basecontainer.py b/omegaconf/basecontainer.py
index 9a25f07..f074827 100644
--- a/omegaconf/basecontainer.py
+++ b/omegaconf/basecontainer.py
@@ -20,12 +20,7 @@ from ._utils import (
     is_structured_config,
 )
 from .base import Container, ContainerMetadata, Node
-from .errors import (
-    MissingMandatoryValue,
-    OmegaConfBaseException,
-    ReadonlyConfigError,
-    ValidationError,
-)
+from .errors import MissingMandatoryValue, ReadonlyConfigError, ValidationError
 
 DEFAULT_VALUE_MARKER: Any = str("__DEFAULT_VALUE_MARKER__")
 
@@ -291,10 +286,7 @@ class BaseContainer(Container, ABC):
             # recursively correct the parent hierarchy after the merge
             self._re_parent()
         except Exception as e:
-            if isinstance(e, OmegaConfBaseException) and e._initialized:
-                raise e
-            else:
-                self._format_and_raise(key=None, value=None, cause=e)
+            self._format_and_raise(key=None, value=None, cause=e)
 
     # noinspection PyProtectedMember
     def _set_item_impl(self, key: Any, value: Any) -> None:
diff --git a/omegaconf/dictconfig.py b/omegaconf/dictconfig.py
index 137221c..82a1636 100644
--- a/omegaconf/dictconfig.py
+++ b/omegaconf/dictconfig.py
@@ -149,10 +149,7 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
 
         # validate get
         if key is not None:
-            try:
-                self._validate_get(key, value)
-            except AttributeError as e:
-                raise ConfigAttributeError(f"Error setting $KEY=$VALUE : {e}")
+            self._validate_get(key, value)
 
         target: Optional[Node]
         if key is None:
@@ -363,11 +360,7 @@ class DictConfig(BaseContainer, MutableMapping[str, Any]):
         try:
             key = self._validate_and_normalize_key(key)
             if self._get_flag("readonly"):
-                self._format_and_raise(
-                    key=key,
-                    value=None,
-                    cause=ReadonlyConfigError("Cannot pop from read-only node"),
-                )
+                raise ReadonlyConfigError("Cannot pop from read-only node")
 
             node = self._get_node(key=key)
             if node is not None:
diff --git a/omegaconf/errors.py b/omegaconf/errors.py
index 6efe646..fc2afd1 100644
--- a/omegaconf/errors.py
+++ b/omegaconf/errors.py
@@ -11,9 +11,9 @@ class OmegaConfBaseException(Exception):
     msg: Optional[str]
     cause: Optional[Exception]
     object_type: Optional[Type[Any]]
-    object_type_str: str
+    object_type_str: Optional[str]
     ref_type: Optional[Type[Any]]
-    ref_type_str: str
+    ref_type_str: Optional[str]
 
     _initialized: bool = False
 

Double crap in error message

```python
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
from dataclasses import dataclass

import hydra
from hydra.core.config_store import ConfigStore


@dataclass
class MySQLConfig:
    driver: str = "mysql"
    host: str = "localhost"
    port: int = 3306
    user: str = "omry"
    password: str = "secret"


cfg_store = ConfigStore.instance()
# Registering the Config class with the name 'config'
cfg_store.store(node=MySQLConfig, name="config")


@hydra.main(config_name="config")
def my_app(cfg: MySQLConfig) -> None:
    # The real type of cfg is DictConfig, but we lie a little to get static type checking.
    # If it swims like a duck and quacks like a duck, it's a "duck".
    print(
        f"Connecting to {cfg.drover} at {cfg.host}:{cfg.port},"
        f" user={cfg.user}, password={cfg.password}"
    )


if __name__ == "__main__":
    my_app()

$ python examples/structured_configs_tutorial/1_basic/my_app.py
...
omegaconf.errors.ConfigAttributeError: Key 'drover' not in 'MySQLConfig'
        full_key: drover
        reference_type=Optional[dict]
        object_type=MySQLConfig

        full_key: drover
        reference_type=Optional[dict]
        object_type=MySQLConfig
```
diff --git a/tests/test_errors.py b/tests/test_errors.py
index e51f15f..2649724 100644
--- a/tests/test_errors.py
+++ b/tests/test_errors.py
@@ -22,6 +22,7 @@ from omegaconf.errors import (
     ConfigValueError,
     KeyValidationError,
     MissingMandatoryValue,
+    OmegaConfBaseException,
 )
 
 from . import (
@@ -52,6 +53,7 @@ class Expected:
     parent_node: Any = lambda cfg: cfg
     object_type_str: Optional[str] = "AUTO"
     ref_type_str: Optional[str] = "AUTO"
+    num_lines: int = 4
 
     def finalize(self, cfg: Any) -> None:
         if self.object_type == "AUTO":
@@ -271,7 +273,7 @@ params = [
             create=lambda: create_struct({"foo": "bar"}),
             op=lambda cfg: cfg.__setitem__("zoo", "zonk"),
             exception_type=KeyError,
-            msg="Error setting zoo=zonk : Key 'zoo' in not in struct",
+            msg="Key 'zoo' in not in struct",
             key="zoo",
         ),
         id="dict,struct:setitem_on_none_existing_key",
@@ -294,6 +296,7 @@ params = [
             exception_type=KeyValidationError,
             msg="Key 'foo' is incompatible with (Color)",
             key="foo",
+            num_lines=7,
         ),
         id="dict,reftype=Dict[Color,str]:,getitem_str_key",
     ),
@@ -420,6 +423,7 @@ params = [
             msg="Union types are not supported:\nx: Union[int, str]",
             object_type_str=None,
             ref_type_str=None,
+            num_lines=5,
         ),
         id="structured:create_with_union_error",
     ),
@@ -904,14 +908,16 @@ def test_errors(expected: Expected, monkeypatch: Any) -> None:
     with pytest.raises(expected.exception_type, match=re.escape(msg)) as einfo:
         try:
             expected.op(cfg)
-        except Exception as e:
+        except Exception:
             # helps in debugging
-            raise e from e
+            raise
     ex = einfo.value
 
     assert ex.object_type == expected.object_type
     assert ex.key == expected.key
     if not expected.low_level:
+        if isinstance(ex, OmegaConfBaseException):
+            assert str(ex).count("\n") == expected.num_lines
         assert ex.parent_node == expected.parent_node(cfg)
         assert ex.child_node == expected.child_node(cfg)
         assert ex.full_key == expected.full_key

pip install -e .[dev]
parse_log_pytest
pytest
pytest pytest-mock
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs @ file:///croot/attrs_1668696182826/work
certifi @ file:///croot/certifi_1671487769961/work/certifi
flit_core @ file:///opt/conda/conda-bld/flit-core_1644941570762/work/source/flit_core
importlib-metadata @ file:///tmp/build/80754af9/importlib-metadata_1648562407465/work
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
-e git+https://github.com/omry/omegaconf.git@634084fcd6605e74ebc8583f4eb4d33f2ecb2d71#egg=omegaconf
packaging @ file:///croot/packaging_1671697413597/work
pluggy @ file:///tmp/build/80754af9/pluggy_1648042572264/work
py @ file:///opt/conda/conda-bld/py_1644396412707/work
pytest==7.1.2
pytest-mock==3.11.1
PyYAML==6.0.1
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
typing_extensions @ file:///croot/typing_extensions_1669924550328/work
zipp @ file:///croot/zipp_1672387121353/work

name: omegaconf
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - attrs=22.1.0=py37h06a4308_0
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - flit-core=3.6.0=pyhd3eb1b0_0
  - importlib-metadata=4.11.3=py37h06a4308_0
  - importlib_metadata=4.11.3=hd3eb1b0_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - packaging=22.0=py37h06a4308_0
  - pip=22.3.1=py37h06a4308_0
  - pluggy=1.0.0=py37h06a4308_1
  - py=1.11.0=pyhd3eb1b0_0
  - pytest=7.1.2=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py37h06a4308_0
  - typing_extensions=4.4.0=py37h06a4308_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zipp=3.11.0=py37h06a4308_0
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - omegaconf==2.0.0rc24
      - pytest-mock==3.11.1
      - pyyaml==6.0.1
prefix: /opt/conda/envs/omegaconf

tests/test_errors.py::test_errors[dict,readonly:pop] tests/test_errors.py::test_errors[dict:pop_invalid] tests/test_errors.py::test_errors[dict:pop_invalid_nested] tests/test_errors.py::test_errors[structured:access_invalid_attribute] tests/test_errors.py::test_errors[dict,struct:access_invalid_attribute] tests/test_errors.py::test_errors[dict,accessing_missing_interpolation] tests/test_errors.py::test_errors[dict,accessing_missing_str_interpolation] tests/test_errors.py::test_errors[dict,struct:set_invalid_attribute] tests/test_errors.py::test_errors[structured:create_with_union_error] tests/test_errors.py::test_errors[list:pop_invalid_key]
tests/test_errors.py::test_errors[structured:update_with_invalid_value] tests/test_errors.py::test_errors[structured:update:none_to_non_optional] tests/test_errors.py::test_errors[dict:update:object_of_illegal_type] tests/test_errors.py::test_errors[structured:setattr,invalid_type_assigned_to_structured] tests/test_errors.py::test_errors[dict,readonly:set_attribute] tests/test_errors.py::test_errors[dict,none_optional:set_none] tests/test_errors.py::test_errors[structured:setattr,invalid_type_assigned_to_field] tests/test_errors.py::test_errors[dict,struct:setitem_on_none_existing_key] tests/test_errors.py::test_errors[dict,struct:getitem_key_not_in_struct] tests/test_errors.py::test_errors[dict,reftype=Dict[Color,str]:,getitem_str_key] tests/test_errors.py::test_errors[dict,reftype=Dict[str,str]:,getitem_color_key] tests/test_errors.py::test_errors[dict,readonly:merge_with] tests/test_errors.py::test_errors[structured:merge,invalid_field_type] tests/test_errors.py::test_errors[structured:merge,adding_an_invalid_key] tests/test_errors.py::test_errors[structured:merge_invalid_dataclass] tests/test_errors.py::test_errors[dict:get_illegal_type] tests/test_errors.py::test_errors[dict:get_object_of_illegal_type] tests/test_errors.py::test_errors[dict_create_none_optional_with_none] tests/test_errors.py::test_errors[dict_create_from_illegal_type] tests/test_errors.py::test_errors[structured:create_from_unsupported_object] tests/test_errors.py::test_errors[dict:set_value:reftype_mismatch] tests/test_errors.py::test_errors[dict,int_element_type:assigned_str_value] tests/test_errors.py::test_errors[dict,readonly:del] tests/test_errors.py::test_errors[list:setattr0] tests/test_errors.py::test_errors[list:setattr1] tests/test_errors.py::test_errors[list:get_nox_ex:invalid_index_type] tests/test_errors.py::test_errors[list:get_node_ex:index_out_of_range] tests/test_errors.py::test_errors[list:get_node_none] tests/test_errors.py::test_errors[list:get_node_missing] tests/test_errors.py::test_errors[list:create_not_optional_with_none] tests/test_errors.py::test_errors[list:append_value_of_illegal_type] tests/test_errors.py::test_errors[list:readonly:pop] tests/test_errors.py::test_errors[list:pop_from_none] tests/test_errors.py::test_errors[list:pop_from_missing] tests/test_errors.py::test_errors[list:subscript_slice_with_missing] tests/test_errors.py::test_errors[list:subscript_index_with_missing] tests/test_errors.py::test_errors[list:subscript:index_out_of_range] tests/test_errors.py::test_errors[list:getitem,illegal_key_type0] tests/test_errors.py::test_errors[list:getitem,illegal_key_type1] tests/test_errors.py::test_errors[list:setitem,illegal_value_type] tests/test_errors.py::test_errors[list:setitem,illegal_key_type] tests/test_errors.py::test_errors[list,readonly:setitem] tests/test_errors.py::test_errors[list,int_elements:assigned_str_element0] tests/test_errors.py::test_errors[list,int_elements:assigned_str_element1] tests/test_errors.py::test_errors[list,not_optional:null_assignment] tests/test_errors.py::test_errors[list,readonly:index_not_found] tests/test_errors.py::test_errors[list,readonly:insert] tests/test_errors.py::test_errors[list:insert_into_none] tests/test_errors.py::test_errors[list:insert_into_missing] tests/test_errors.py::test_errors[list:get_from_none] tests/test_errors.py::test_errors[list:get_from_missing] tests/test_errors.py::test_errors[list:readonly:sort0] tests/test_errors.py::test_errors[list:sort_from_none] tests/test_errors.py::test_errors[list:sort_from_missing] tests/test_errors.py::test_errors[list:readonly:sort1] tests/test_errors.py::test_errors[list:iter_none] tests/test_errors.py::test_errors[list:iter_missing] tests/test_errors.py::test_errors[list,readonly:del]
omegaconf/dictconfig.py omegaconf/basecontainer.py omegaconf/_utils.py omegaconf/errors.py
omegaconf/dictconfig.py omegaconf/basecontainer.py omegaconf/_utils.py omegaconf/errors.py