diff --git a/cpp/src/arrow/filesystem/filesystem_test.cc b/cpp/src/arrow/filesystem/filesystem_test.cc index 8477647b2cd73..5072c3a8c25b1 100644 --- a/cpp/src/arrow/filesystem/filesystem_test.cc +++ b/cpp/src/arrow/filesystem/filesystem_test.cc @@ -20,6 +20,7 @@ #include #include +#include #include #include "arrow/filesystem/filesystem.h" @@ -632,6 +633,13 @@ TEST_F(TestMockFS, FileSystemFromUri) { ASSERT_OK_AND_ASSIGN(fs_, FileSystemFromUri("mock:///foo/bar?q=zzz", &path)); ASSERT_EQ(path, "foo/bar"); CheckDirs({}); + ASSERT_OK_AND_ASSIGN(fs_, FileSystemFromUri("mock:/folder+name/bar?q=zzz", &path)); + ASSERT_EQ(path, "folder+name/bar"); + CheckDirs({}); + EXPECT_RAISES_WITH_MESSAGE_THAT( + Invalid, ::testing::HasSubstr("syntax error at character ' ' (position 12)"), + FileSystemFromUri("mock:/folder name/bar", &path)); + CheckDirs({}); } //////////////////////////////////////////////////////////////////////////// diff --git a/cpp/src/arrow/util/uri.cc b/cpp/src/arrow/util/uri.cc index 9c0f7f9a59630..6c0787a87e046 100644 --- a/cpp/src/arrow/util/uri.cc +++ b/cpp/src/arrow/util/uri.cc @@ -250,9 +250,16 @@ Status Uri::Parse(const std::string& uri_string) { const auto& s = impl_->KeepString(uri_string); impl_->string_rep_ = s; const char* error_pos; - if (uriParseSingleUriExA(&impl_->uri_, s.data(), s.data() + s.size(), &error_pos) != - URI_SUCCESS) { - return Status::Invalid("Cannot parse URI: '", uri_string, "'"); + int retval = + uriParseSingleUriExA(&impl_->uri_, s.data(), s.data() + s.size(), &error_pos); + if (retval != URI_SUCCESS) { + if (retval == URI_ERROR_SYNTAX) { + return Status::Invalid("Cannot parse URI: '", uri_string, + "' due to syntax error at character '", *error_pos, + "' (position ", error_pos - s.data(), ")"); + } else { + return Status::Invalid("Cannot parse URI: '", uri_string, "'"); + } } const auto scheme = TextRangeToView(impl_->uri_.scheme);