Handle C++ exceptions raised during `finfo`/`iinfo` calls (#109743)

Partially fixes https://github.com/pytorch/pytorch/issues/109737
Pull Request resolved: https://github.com/pytorch/pytorch/pull/109743
Approved by: https://github.com/albanD
ghstack dependencies: #109744
diff --git a/torch/csrc/TypeInfo.cpp b/torch/csrc/TypeInfo.cpp
index 3531cc4..00ad0e7 100644
--- a/torch/csrc/TypeInfo.cpp
+++ b/torch/csrc/TypeInfo.cpp
@@ -112,6 +112,7 @@
 }
 
 static PyObject* THPFInfo_eps(THPFInfo* self, void*) {
+  HANDLE_TH_ERRORS
   return AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES_AND4(
       at::kHalf,
       at::ScalarType::BFloat16,
@@ -124,9 +125,11 @@
             std::numeric_limits<
                 at::scalar_value_type<scalar_t>::type>::epsilon());
       });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPFInfo_max(THPFInfo* self, void*) {
+  HANDLE_TH_ERRORS
   return AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES_AND4(
       at::kHalf,
       at::ScalarType::BFloat16,
@@ -138,9 +141,11 @@
         return PyFloat_FromDouble(
             std::numeric_limits<at::scalar_value_type<scalar_t>::type>::max());
       });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPFInfo_min(THPFInfo* self, void*) {
+  HANDLE_TH_ERRORS
   return AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES_AND4(
       at::kHalf,
       at::ScalarType::BFloat16,
@@ -153,9 +158,11 @@
             std::numeric_limits<
                 at::scalar_value_type<scalar_t>::type>::lowest());
       });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPIInfo_max(THPIInfo* self, void*) {
+  HANDLE_TH_ERRORS
   if (at::isIntegralType(self->type, /*includeBool=*/false)) {
     return AT_DISPATCH_INTEGRAL_TYPES(self->type, "max", [] {
       return THPUtils_packInt64(std::numeric_limits<scalar_t>::max());
@@ -165,9 +172,11 @@
   return AT_DISPATCH_QINT_AND_SUB_BYTE_TYPES(self->type, "max", [] {
     return THPUtils_packInt64(std::numeric_limits<underlying_t>::max());
   });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPIInfo_min(THPIInfo* self, void*) {
+  HANDLE_TH_ERRORS
   if (at::isIntegralType(self->type, /*includeBool=*/false)) {
     return AT_DISPATCH_INTEGRAL_TYPES(self->type, "min", [] {
       return THPUtils_packInt64(std::numeric_limits<scalar_t>::lowest());
@@ -177,16 +186,20 @@
   return AT_DISPATCH_QINT_AND_SUB_BYTE_TYPES(self->type, "min", [] {
     return THPUtils_packInt64(std::numeric_limits<underlying_t>::lowest());
   });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPIInfo_dtype(THPIInfo* self, void*) {
+  HANDLE_TH_ERRORS
   auto primary_name = torch::utils::getDtypeNames(self->type).first;
   return AT_DISPATCH_INTEGRAL_TYPES(self->type, "dtype", [&primary_name] {
     return PyUnicode_FromString(primary_name.data());
   });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPFInfo_smallest_normal(THPFInfo* self, void*) {
+  HANDLE_TH_ERRORS
   return AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES_AND4(
       at::kHalf,
       at::ScalarType::BFloat16,
@@ -198,6 +211,7 @@
         return PyFloat_FromDouble(
             std::numeric_limits<at::scalar_value_type<scalar_t>::type>::min());
       });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPFInfo_tiny(THPFInfo* self, void*) {
@@ -206,6 +220,7 @@
 }
 
 static PyObject* THPFInfo_resolution(THPFInfo* self, void*) {
+  HANDLE_TH_ERRORS
   return AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES_AND4(
       at::kHalf,
       at::ScalarType::BFloat16,
@@ -219,9 +234,11 @@
             -std::numeric_limits<
                 at::scalar_value_type<scalar_t>::type>::digits10));
       });
+  END_HANDLE_TH_ERRORS
 }
 
 static PyObject* THPFInfo_dtype(THPFInfo* self, void*) {
+  HANDLE_TH_ERRORS
   auto primary_name = torch::utils::getDtypeNames(self->type).first;
   return AT_DISPATCH_FLOATING_AND_COMPLEX_TYPES_AND4(
       at::kHalf,
@@ -231,10 +248,12 @@
       self->type,
       "dtype",
       [&primary_name] { return PyUnicode_FromString(primary_name.data()); });
+  END_HANDLE_TH_ERRORS
 }
 
 PyObject* THPFInfo_str(THPFInfo* self) {
   std::ostringstream oss;
+  const auto dtypeStr = THPFInfo_dtype(self, nullptr);
   oss << "finfo(resolution="
       << PyFloat_AsDouble(THPFInfo_resolution(self, nullptr));
   oss << ", min=" << PyFloat_AsDouble(THPFInfo_min(self, nullptr));
@@ -243,19 +262,23 @@
   oss << ", smallest_normal="
       << PyFloat_AsDouble(THPFInfo_smallest_normal(self, nullptr));
   oss << ", tiny=" << PyFloat_AsDouble(THPFInfo_tiny(self, nullptr));
-  oss << ", dtype=" << PyUnicode_AsUTF8(THPFInfo_dtype(self, nullptr)) << ")";
-
-  return THPUtils_packString(oss.str().c_str());
+  if (dtypeStr != nullptr) {
+    oss << ", dtype=" << PyUnicode_AsUTF8(dtypeStr) << ")";
+  }
+  return !PyErr_Occurred() ? THPUtils_packString(oss.str().c_str()) : nullptr;
 }
 
 PyObject* THPIInfo_str(THPIInfo* self) {
   std::ostringstream oss;
 
+  const auto dtypeStr = THPIInfo_dtype(self, nullptr);
   oss << "iinfo(min=" << PyLong_AsDouble(THPIInfo_min(self, nullptr));
   oss << ", max=" << PyLong_AsDouble(THPIInfo_max(self, nullptr));
-  oss << ", dtype=" << PyUnicode_AsUTF8(THPIInfo_dtype(self, nullptr)) << ")";
+  if (dtypeStr) {
+    oss << ", dtype=" << PyUnicode_AsUTF8(dtypeStr) << ")";
+  }
 
-  return THPUtils_packString(oss.str().c_str());
+  return !PyErr_Occurred() ? THPUtils_packString(oss.str().c_str()) : nullptr;
 }
 
 // NOLINTNEXTLINE(modernize-avoid-c-arrays,cppcoreguidelines-avoid-non-const-global-variables,cppcoreguidelines-avoid-c-arrays)