|
1 | 1 | #include <sourcemeta/blaze/configuration.h> |
2 | 2 | #include <sourcemeta/core/io.h> |
3 | 3 |
|
4 | | -#include <algorithm> // std::ranges::any_of |
5 | | -#include <cassert> // assert |
6 | | -#include <string> // std::string |
| 4 | +#include <algorithm> // std::ranges::any_of |
| 5 | +#include <cassert> // assert |
| 6 | +#include <string> // std::string |
| 7 | +#include <system_error> // std::error_code |
7 | 8 |
|
8 | 9 | namespace sourcemeta::blaze { |
9 | 10 |
|
10 | 11 | auto Configuration::find(const std::filesystem::path &path) |
11 | 12 | -> std::optional<std::filesystem::path> { |
12 | | - const auto canonical{sourcemeta::core::weakly_canonical(path)}; |
| 13 | + // Note we use non-throwing overloads of filesystem functions to gracefully |
| 14 | + // handle I/O errors on FUSE and other unusual filesystems |
| 15 | + std::filesystem::path canonical; |
| 16 | + try { |
| 17 | + canonical = sourcemeta::core::weakly_canonical(path); |
| 18 | + } catch (const std::filesystem::filesystem_error &) { |
| 19 | + return std::nullopt; |
| 20 | + } |
| 21 | + |
13 | 22 | assert(canonical.is_absolute()); |
14 | | - auto current = std::filesystem::is_directory(canonical) |
| 23 | + std::error_code error; |
| 24 | + auto current = std::filesystem::is_directory(canonical, error) |
15 | 25 | ? canonical |
16 | 26 | : canonical.parent_path(); |
17 | 27 |
|
18 | 28 | while (!current.empty()) { |
19 | 29 | auto candidate = current / "jsonschema.json"; |
20 | | - if (std::filesystem::exists(candidate) && |
21 | | - std::filesystem::is_regular_file(candidate)) { |
| 30 | + if (std::filesystem::exists(candidate, error) && |
| 31 | + std::filesystem::is_regular_file(candidate, error)) { |
22 | 32 | return candidate; |
23 | 33 | } |
24 | 34 |
|
|
0 commit comments