Repository: TREX-CoE/trexio (language: python)

Issue:
Add return code to open
If we want to return an exit code like all other functions, the first argument (`file`) would need to be of type `trexio_t**`, which is quite inconevnient for users.

So it is probably better to add the return code as a last argument of this function, passed by address.


Discussion / hints:

Fix patch:
diff --git a/src/pytrexio.i b/src/pytrexio.i
index 1665eb9f..87da0645 100644
--- a/src/pytrexio.i
+++ b/src/pytrexio.i
@@ -37,6 +37,7 @@
 %apply int *OUTPUT { int64_t* const num};
 %apply float *OUTPUT { float* const num};
 %apply float *OUTPUT { double* const num};
+%apply int *OUTPUT { trexio_exit_code* const rc_open};
 
 /* Does not work for arrays (SIGSEGV) */
 
diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org
index cc0d2c6f..b1a6d6e1 100644
--- a/src/templates_front/templator_front.org
+++ b/src/templates_front/templator_front.org
@@ -703,23 +703,31 @@ struct trexio_back_end_s {
 *** C
 
    #+begin_src c :tangle prefix_front.h :exports none
-trexio_t* trexio_open(const char* file_name, const char mode, const back_end_t back_end);
+trexio_t* trexio_open(const char* file_name, const char mode, 
+                      const back_end_t back_end, trexio_exit_code* const rc_open);
    #+end_src
 
    #+begin_src c :tangle prefix_front.c
 trexio_t*
 trexio_open(const char* file_name, const char mode,
-	    const back_end_t back_end)
+	    const back_end_t back_end, trexio_exit_code* const rc_open)
 {
 
-  if (file_name == NULL) return NULL;
-  if (file_name[0] == '\0') return NULL;
+  if (file_name == NULL || file_name[0] == '\0') {
+    if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_1;
+    return NULL;
+  }
   /* Check overflow in file_name */
 
-  if (back_end <  0) return NULL;
-  if (back_end >= TREXIO_INVALID_BACK_END) return NULL;
+  if (back_end <  0 || back_end >= TREXIO_INVALID_BACK_END) {
+    if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_3;
+    return NULL;
+  }
 
-  if (mode != 'r' && mode != 'w') return NULL;
+  if (mode != 'r' && mode != 'w') {
+    if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_2;
+    return NULL;
+  }
 
   trexio_t* result = NULL;
   void* result_tmp = NULL;
@@ -744,17 +752,18 @@ trexio_open(const char* file_name, const char mode,
 
   assert (result != NULL);    /* TODO: Error handling */
 
-
   /* Data for the parent type */
 
   strncpy(result->file_name, file_name, TREXIO_MAX_FILENAME_LENGTH);
   if (result->file_name[TREXIO_MAX_FILENAME_LENGTH-1] != '\0') {
+    if (rc_open != NULL) *rc_open = TREXIO_INVALID_ARG_1;
     free(result);
     return NULL;
   }
 
   strncpy(result->version, PACKAGE_VERSION, 16);
   if (result->version[15] != '\0') {
+    if (rc_open != NULL) *rc_open = TREXIO_FAILURE;
     free(result);
     return NULL;
   }
@@ -792,12 +801,14 @@ trexio_open(const char* file_name, const char mode,
   }
 
   if (rc != TREXIO_SUCCESS) {
+    if (rc_open != NULL) *rc_open = TREXIO_OPEN_ERROR;
     free(result);
     return NULL;
   }
 
   rc = trexio_has_metadata_package_version(result);
   if (rc == TREXIO_FAILURE) {
+    if (rc_open != NULL) *rc_open = TREXIO_OPEN_ERROR;
     free(result);
     return NULL;
   }
@@ -821,6 +832,7 @@ trexio_open(const char* file_name, const char mode,
   }
 
   if (rc != TREXIO_SUCCESS) {
+    if (rc_open != NULL) *rc_open = TREXIO_OPEN_ERROR;
     free(result);
     return NULL;
   }
@@ -847,10 +859,12 @@ trexio_open(const char* file_name, const char mode,
   }
 
   if (rc != TREXIO_SUCCESS) {
+    if (rc_open != NULL) *rc_open = TREXIO_LOCK_ERROR;
     free(result);
     return NULL;
   }
 
+  if (rc_open != NULL) *rc_open = TREXIO_SUCCESS;
   return result;
 }
    #+end_src
@@ -859,12 +873,13 @@ trexio_open(const char* file_name, const char mode,
 
    #+begin_src f90 :tangle prefix_fortran.f90
 interface
-   integer(8) function trexio_open_c (filename, mode, backend) bind(C, name="trexio_open")
+   integer(8) function trexio_open_c (filename, mode, backend, rc_open) bind(C, name="trexio_open")
      use, intrinsic :: iso_c_binding
      import
      character(kind=c_char), dimension(*)       :: filename
      character, intent(in), value               :: mode
      integer(trexio_backend), intent(in), value :: backend
+     integer(trexio_exit_code), intent(out)     :: rc_open
    end function trexio_open_c
 end interface
    #+end_src
@@ -894,11 +909,22 @@ def open(file_name: str, mode: str, back_end: int):
     >>> trex_file = tr_open("example.h5", "w", TREXIO_HDF5)
     """
 
+    # The new trexio_open function is capable of returning error code which SWIG can append to the output trexio_s file struct
+    # However, if trexio_s* == NULL, then SWIG returns only an error code rc_open instead of a list [trexio_s, rc_open]
+    # Thus, the following try/except sequence is needed
     try:
-        trexio_file = pytr.trexio_open(file_name, mode, back_end)
-        assert trexio_file is not None
+        return_obj = pytr.trexio_open(file_name, mode, back_end)
+        assert return_obj is not None
+        if isinstance(return_obj, int):
+            raise Error(return_obj)
+        else:
+            rc_open = return_obj[1]
+            # this is a sanity check in case the code evolves and SWIG issue is patched
+            if rc_open == TREXIO_SUCCESS:
+                trexio_file = return_obj[0]
+                assert trexio_file is not None
     except AssertionError:
-        raise Exception(f"Could not open TREXIO file {file_name} using trexio_open function. Please make sure that there are no typos in the file name.")
+        raise Exception(f"Could not open TREXIO file {file_name} using trexio_open function. The return value is None (NULL pointer).")
 
     return trexio_file
    #+end_src
@@ -3056,18 +3082,19 @@ def has_$group_str$(trexio_file) -> bool:
 
   #+begin_src f90 :tangle helper_fortran.f90
 contains
-   integer(8) function trexio_open (filename, mode, backend)
+   integer(8) function trexio_open (filename, mode, backend, rc_open)
      use, intrinsic :: iso_c_binding, only : c_null_char
      implicit none
      character(len=*), intent(in)                 :: filename
      character, intent(in), value                 :: mode
      integer(trexio_backend), intent(in), value   :: backend
+     integer(trexio_exit_code), intent(out)       :: rc_open
      character(len=len_trim(filename)+1) :: filename_c
-     integer :: rc
+     integer(trexio_exit_code) :: rc
 
      filename_c = trim(filename) // c_null_char
-     trexio_open = trexio_open_c(filename_c, mode, backend)
-     if (trexio_open == 0_8) then
+     trexio_open = trexio_open_c(filename_c, mode, backend, rc_open)
+     if (trexio_open == 0_8 .or. rc_open /= TREXIO_SUCCESS) then
        return
      endif
      rc = trexio_set_one_based(trexio_open)


Test patch:
diff --git a/python/test/test_api.py b/python/test/test_api.py
index ae1a1ab6..f6b151da 100644
--- a/python/test/test_api.py
+++ b/python/test/test_api.py
@@ -49,7 +49,7 @@
 try:
     trexio.write_nucleus_num(test_file, -100)
 except trexio.Error:
-    print("Writing negative nucleus_num: checked.")
+    print("Raise error for an attempt to write negative nucleus_num: checked.")
 
 # write nucleus_num in the file
 try:
@@ -60,7 +60,7 @@
 try:
     trexio.write_nucleus_num(test_file, nucleus_num*2)
 except trexio.Error:
-    print("Attempt to overwrite nucleus_num: checked.")
+    print("Raise error for an attempt to overwrite nucleus_num: checked.")
 
 # initialize charge arrays as a list and convert it to numpy array
 charges = [6., 6., 6., 6., 6., 6., 1., 1., 1., 1., 1., 1.]
@@ -199,7 +199,7 @@
 if trexio.has_mo_num(test_file2):
     rmo_num = trexio.read_mo_num(test_file2)
 else:
-    print("Not reading the non-existing variable mo_num.")
+    print("Pass on reading the non-existing variable mo_num: checked")
 
 # close TREXIO file
 #trexio.close(test_file2)
@@ -215,3 +215,16 @@
 
 #==========================================================#
 
+#==========================================================#
+#======= OPEN NON-EXISTING FILE TO TEST TREXIO.OPEN =======#
+#==========================================================#
+
+try:
+    void_file = trexio.File('non_existing.file', 'r', TEST_TREXIO_BACKEND)
+except trexio.Error as e:
+    if e.error == trexio.TREXIO_OPEN_ERROR:
+        print("Opening non-existing file returns TREXIO_OPEN_ERROR: checked")
+    else:
+        raise ValueError("[DEV]: error handling of trexio_open function has changed; check the consistency")
+
+#==========================================================#
diff --git a/tests/io_all.c b/tests/io_all.c
index 4f4709c4..81179cfa 100644
--- a/tests/io_all.c
+++ b/tests/io_all.c
@@ -72,7 +72,7 @@ int test_write(const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // check that certain data does not exist in the file
@@ -97,7 +97,7 @@ int test_write(const char* file_name, const back_end_t backend) {
   assert (rc == TREXIO_SUCCESS);
  
   // reopen file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // check if the written data exists in the file
@@ -125,7 +125,7 @@ int test_write(const char* file_name, const back_end_t backend) {
   assert (rc == TREXIO_SUCCESS);
 
   // open file again in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write some missing blocks (e.g. if forgot last time)
@@ -156,7 +156,7 @@ int test_read(const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open existing file on 'read' mode [created by test_write]
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read nucleus_num
@@ -211,7 +211,7 @@ int test_read(const char* file_name, const back_end_t backend) {
   const char* file_name2 = "test_nonexisting";
   trexio_t* file2 = NULL;
 
-  file2 = trexio_open(file_name2, 'r', backend);
+  file2 = trexio_open(file_name2, 'r', backend, &rc);
   assert (file2 == NULL);
 
 /*================= END OF TEST =====================*/
diff --git a/tests/io_dset_float_hdf5.c b/tests/io_dset_float_hdf5.c
index d645808c..90174cd3 100644
--- a/tests/io_dset_float_hdf5.c
+++ b/tests/io_dset_float_hdf5.c
@@ -34,7 +34,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -65,7 +65,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset exists
@@ -100,7 +100,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_dset_float_text.c b/tests/io_dset_float_text.c
index 4e21d25d..f083ce9b 100644
--- a/tests/io_dset_float_text.c
+++ b/tests/io_dset_float_text.c
@@ -34,7 +34,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -65,7 +65,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset exists
@@ -100,7 +100,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_dset_int_hdf5.c b/tests/io_dset_int_hdf5.c
index 7d9e1a6f..49ff5bba 100644
--- a/tests/io_dset_int_hdf5.c
+++ b/tests/io_dset_int_hdf5.c
@@ -21,7 +21,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -52,7 +52,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file 
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset exists
@@ -87,7 +87,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_dset_int_text.c b/tests/io_dset_int_text.c
index 15443276..ca6ded23 100644
--- a/tests/io_dset_int_text.c
+++ b/tests/io_dset_int_text.c
@@ -21,7 +21,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -52,7 +52,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file 
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset exists
@@ -87,7 +87,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_dset_str_hdf5.c b/tests/io_dset_str_hdf5.c
index cb97f425..fed85bc0 100644
--- a/tests/io_dset_str_hdf5.c
+++ b/tests/io_dset_str_hdf5.c
@@ -33,7 +33,7 @@ static int test_write_dset_str (const char* file_name, const back_end_t backend)
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -65,7 +65,7 @@ static int test_has_dset_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset of strings exists
@@ -100,7 +100,7 @@ static int test_read_dset_str (const char* file_name, const back_end_t backend)
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_dset_str_text.c b/tests/io_dset_str_text.c
index 1d8e7dd5..89171552 100644
--- a/tests/io_dset_str_text.c
+++ b/tests/io_dset_str_text.c
@@ -33,7 +33,7 @@ static int test_write_dset_str (const char* file_name, const back_end_t backend)
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -65,7 +65,7 @@ static int test_has_dset_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset of strings exists
@@ -100,7 +100,7 @@ static int test_read_dset_str (const char* file_name, const back_end_t backend)
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_num_hdf5.c b/tests/io_num_hdf5.c
index 8cac31cf..e0572369 100644
--- a/tests/io_num_hdf5.c
+++ b/tests/io_num_hdf5.c
@@ -20,7 +20,7 @@ static int test_write_num (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -55,7 +55,7 @@ static int test_has_num (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written num variable exists
@@ -90,7 +90,7 @@ static int test_read_num (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_num_text.c b/tests/io_num_text.c
index 9f779cde..3c299aa3 100644
--- a/tests/io_num_text.c
+++ b/tests/io_num_text.c
@@ -20,7 +20,7 @@ static int test_write_num (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -55,7 +55,7 @@ static int test_has_num (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written num variable exists
@@ -90,7 +90,7 @@ static int test_read_num (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_safe_dset_float_hdf5.c b/tests/io_safe_dset_float_hdf5.c
index f70fad77..318ed4a1 100644
--- a/tests/io_safe_dset_float_hdf5.c
+++ b/tests/io_safe_dset_float_hdf5.c
@@ -35,7 +35,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -75,7 +75,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset exists
@@ -106,7 +106,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_safe_dset_float_text.c b/tests/io_safe_dset_float_text.c
index 709abd09..2d339a02 100644
--- a/tests/io_safe_dset_float_text.c
+++ b/tests/io_safe_dset_float_text.c
@@ -35,7 +35,7 @@ static int test_write_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write numerical attribute in an empty file
@@ -75,7 +75,7 @@ static int test_has_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written dataset exists
@@ -106,7 +106,7 @@ static int test_read_dset (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read numerical attribute from the file
diff --git a/tests/io_str_hdf5.c b/tests/io_str_hdf5.c
index 251b5e33..eaafff08 100644
--- a/tests/io_str_hdf5.c
+++ b/tests/io_str_hdf5.c
@@ -21,7 +21,7 @@ static int test_write_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write string attribute in an empty file
@@ -49,7 +49,7 @@ static int test_has_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written string attribute exists
@@ -83,7 +83,7 @@ static int test_read_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read string attribute from the file
diff --git a/tests/io_str_text.c b/tests/io_str_text.c
index d74e7d28..59cfc05a 100644
--- a/tests/io_str_text.c
+++ b/tests/io_str_text.c
@@ -21,7 +21,7 @@ static int test_write_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write string attribute in an empty file
@@ -49,7 +49,7 @@ static int test_has_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written string attribute exists
@@ -83,7 +83,7 @@ static int test_read_str (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
 
   // read string attribute from the file
diff --git a/tests/open_hdf5.c b/tests/open_hdf5.c
index 88ef17f9..20bc3397 100644
--- a/tests/open_hdf5.c
+++ b/tests/open_hdf5.c
@@ -19,8 +19,9 @@ static int test_open_w (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
 
   // close current session
   rc = trexio_close(file);
@@ -42,8 +43,9 @@ static int test_open_r (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
 
   // close current session
   rc = trexio_close(file);
@@ -55,18 +57,38 @@ static int test_open_r (const char* file_name, const back_end_t backend) {
 }
 
 
-static int test_open_void (const char* file_name, const back_end_t backend) {
+static int test_open_errors (const back_end_t backend) {
 
-/* Try to open the non-existing TREXIO file in 'read' mode */
+/* Try to call trexio_open with bad arguments */
 
   trexio_t* file = NULL;
   trexio_exit_code rc;
 
 /*================= START OF TEST ==================*/
 
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR
+  file = trexio_open(TREXIO_VOID, 'r', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_OPEN_ERROR);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open file with empty file name, should return TREXIO_INVALID_ARG_1
+  file = trexio_open("", 'w', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_1);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2
+  file = trexio_open(TREXIO_FILE, 'k', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_2);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3
+  file = trexio_open(TREXIO_VOID, 'w', 666, &rc);
   assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_3);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
 
 /*================= END OF TEST ==================*/
 
@@ -84,7 +106,7 @@ int main(void) {
 
   test_open_w     (TREXIO_FILE, TEST_BACKEND);
   test_open_r     (TREXIO_FILE, TEST_BACKEND);
-  test_open_void  (TREXIO_VOID, TEST_BACKEND);
+  test_open_errors(TEST_BACKEND);
 
   rc = system(RM_COMMAND);
   assert (rc == 0);
diff --git a/tests/open_text.c b/tests/open_text.c
index 4b163114..0aa904ab 100644
--- a/tests/open_text.c
+++ b/tests/open_text.c
@@ -19,8 +19,9 @@ static int test_open_w (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
 
   // close current session
   rc = trexio_close(file);
@@ -42,8 +43,9 @@ static int test_open_r (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'r', backend);
+  file = trexio_open(file_name, 'r', backend, &rc);
   assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
 
   // close current session
   rc = trexio_close(file);
@@ -55,18 +57,38 @@ static int test_open_r (const char* file_name, const back_end_t backend) {
 }
 
 
-static int test_open_void (const char* file_name, const back_end_t backend) {
+static int test_open_errors (const back_end_t backend) {
 
-/* Try to open the non-existing TREXIO file in 'read' mode */
+/* Try to call trexio_open with bad arguments */
 
   trexio_t* file = NULL;
   trexio_exit_code rc;
 
 /*================= START OF TEST ==================*/
 
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend);
+  // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR
+  file = trexio_open(TREXIO_VOID, 'r', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_OPEN_ERROR);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open file with empty file name, should return TREXIO_INVALID_ARG_1
+  file = trexio_open("", 'w', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_1);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2
+  file = trexio_open(TREXIO_FILE, 'k', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_2);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3
+  file = trexio_open(TREXIO_VOID, 'w', 666, &rc);
   assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_3);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
 
 /*================= END OF TEST ==================*/
 
@@ -84,7 +106,7 @@ int main(void) {
 
   test_open_w     (TREXIO_FILE, TEST_BACKEND);
   test_open_r     (TREXIO_FILE, TEST_BACKEND);
-  test_open_void  (TREXIO_VOID, TEST_BACKEND);
+  test_open_errors(TEST_BACKEND);
 
   rc = system(RM_COMMAND);
   assert (rc == 0);
diff --git a/tests/overwrite_all_hdf5.c b/tests/overwrite_all_hdf5.c
index ae0bad77..bcbbaf5f 100644
--- a/tests/overwrite_all_hdf5.c
+++ b/tests/overwrite_all_hdf5.c
@@ -47,7 +47,7 @@ static int test_write (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write the data
@@ -95,7 +95,7 @@ static int test_overwrite (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written data cannot be overwritten
diff --git a/tests/overwrite_all_text.c b/tests/overwrite_all_text.c
index 4e5ef428..11e55185 100644
--- a/tests/overwrite_all_text.c
+++ b/tests/overwrite_all_text.c
@@ -47,7 +47,7 @@ static int test_write (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // write the data
@@ -95,7 +95,7 @@ static int test_overwrite (const char* file_name, const back_end_t backend) {
 /*================= START OF TEST ==================*/
 
   // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend);
+  file = trexio_open(file_name, 'w', backend, &rc);
   assert (file != NULL);
 
   // check that the previously written data cannot be overwritten
diff --git a/tests/test_f.f90 b/tests/test_f.f90
index 1f0c230f..42f93871 100644
--- a/tests/test_f.f90
+++ b/tests/test_f.f90
@@ -9,12 +9,16 @@ program test_trexio
   call test_read('test_write_f.dir', TREXIO_TEXT)
   call system('rm -rf test_write_f.dir')
 
+  call test_read_void('test_write_f.dir', TREXIO_TEXT)
+
   call system('rm -rf test_write_f.h5')
   print *, 'call test_write(''test_write_f.h5'', TREXIO_HDF5)'
   call test_write('test_write_f.h5', TREXIO_HDF5)
   print *, 'call test_read(''test_write_f.h5'', TREXIO_HDF5)'
   call test_read('test_write_f.h5', TREXIO_HDF5)
   call system('rm -rf test_write_f.h5')
+  
+  call test_read_void('test_write_f.h5', TREXIO_HDF5)
 
 end program test_trexio
 
@@ -68,7 +72,8 @@ subroutine test_write(file_name, back_end)
 
 ! ================= START OF TEST ===================== !
 
-  trex_file = trexio_open(file_name, 'w', back_end)
+  trex_file = trexio_open(file_name, 'w', back_end, rc)
+  call trexio_assert(rc, TREXIO_SUCCESS)
 
   rc = trexio_has_nucleus_num(trex_file)
   call trexio_assert(rc, TREXIO_HAS_NOT, 'SUCCESS HAS NOT 1')
@@ -144,8 +149,8 @@ subroutine test_read(file_name, back_end)
 
 ! ================= START OF TEST ===================== !
 
-  trex_file = trexio_open(file_name, 'r', back_end)
-
+  trex_file = trexio_open(file_name, 'r', back_end, rc)
+  call trexio_assert(rc, TREXIO_SUCCESS)
 
   rc = trexio_read_nucleus_num(trex_file, num_read)
   call trexio_assert(rc, TREXIO_SUCCESS)
@@ -214,3 +219,29 @@ subroutine test_read(file_name, back_end)
 
 end subroutine test_read
 
+subroutine test_read_void(file_name, back_end)
+
+! ============ Test read of non-existing file =============== !
+
+  use trexio
+  implicit none
+
+  character*(*), intent(in) :: file_name
+  integer, intent(in) :: back_end
+
+  integer(8) :: trex_file
+  integer :: rc = 1
+  character(128) :: str
+
+! ================= START OF TEST ===================== !
+
+  trex_file = trexio_open(file_name, 'r', back_end, rc)
+  call trexio_assert(rc, TREXIO_OPEN_ERROR)
+
+  call trexio_string_of_error(rc, str)
+  print *, trim(str)
+
+! ================= END OF TEST ===================== !
+
+end subroutine test_read_void
+