We have seen that we can enable exceptions per stream object, s, with s.exceptions(s.failbit | s.badbit). This means, that there is no way to use, for example, the std::ifstream instance's constructor for opening a file if we want to get an exception when opening that file is not possible:
ifstream f {"non_existant.txt"};
f.exceptions(...); // too late for an exception
This is a pity because exceptions actually promise that they make error handling less clumsy compared to old-school C-style code, which is riddled with loads of if branches, which handle errors after every step.
If we played around trying to provoke various reasons for streams to fail, we would realize that there are no different exceptions being thrown. This way, we can only find out when we get an error, but not what specific error (This is, of course, not true for exception handling in general, but for the STL stream library). That is why we additionally consulted the value of errno. This global variable is an ancient construct, which has already been used in the old days when there were no C++ or exceptions in general.
If any system-related function has seen an error condition, it is able to set the errno variable to something other than 0 (0 describes the absence of errors), and then the caller is able to read that error number and look up what its value means. The only problem with this is that when we have a multithreaded application, and all the threads use functions that can set this error variable, whose error value is it? If we read it even though there is no error, it could carry an error value because some other system function running in a different thread may have experienced an error. Luckily, this flaw has been gone since C++11, where every thread in a process sees its own errno variable.
Without elaborating the ups and downs of an ancient error indication method, it can give us useful extra information when an exception is triggered on system-based things such as file streams. Exceptions tell us when it happened, and errno can tell us what happened if it happened at the system level.