Skip to content

Commit 54204d5

Browse files
committed
Replace IOExceptions
1 parent d41bbe6 commit 54204d5

File tree

8 files changed

+46
-43
lines changed

8 files changed

+46
-43
lines changed

src/common/api_utils.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include "api_utils.hpp"
2-
#include <sys/stat.h>
3-
#include "storage/irc_catalog.hpp"
42
#include "credentials/credential_provider.hpp"
3+
#include "duckdb/common/exception/http_exception.hpp"
4+
#include "storage/irc_catalog.hpp"
5+
#include <sys/stat.h>
56

67
namespace duckdb {
78

@@ -45,7 +46,7 @@ string APIUtils::GetRequest(ClientContext &context, const IRCEndpointBuilder &en
4546
curl_easy_strerror(res));
4647
if (res != CURLcode::CURLE_OK) {
4748
string error = curl_easy_strerror(res);
48-
throw IOException("Curl Request to '%s' failed with error: '%s'", url, error);
49+
throw HTTPException("Curl Request to '%s' failed with error: '%s'", url, error);
4950
}
5051

5152
return readBuffer;
@@ -116,8 +117,8 @@ string APIUtils::GetRequestAws(ClientContext &context, IRCEndpointBuilder endpoi
116117
} else {
117118
Aws::StringStream resBody;
118119
resBody << res->GetResponseBody().rdbuf();
119-
throw IOException("Failed to query %s, http error %d thrown. Message: %s", req->GetUri().GetURIString(true),
120-
res->GetResponseCode(), resBody.str());
120+
throw HTTPException("Failed to query %s, http error %d thrown. Message: %s", req->GetUri().GetURIString(true),
121+
res->GetResponseCode(), resBody.str());
121122
}
122123
}
123124

@@ -177,7 +178,7 @@ string APIUtils::DeleteRequest(const string &url, const string &token, curl_slis
177178

178179
if (res != CURLcode::CURLE_OK) {
179180
string error = curl_easy_strerror(res);
180-
throw IOException("Curl DELETE Request to '%s' failed with error: '%s'", url, error);
181+
throw HTTPException("Curl DELETE Request to '%s' failed with error: '%s'", url, error);
181182
}
182183

183184
return readBuffer;
@@ -227,7 +228,7 @@ string APIUtils::PostRequest(ClientContext &context, const string &url, const st
227228
curl_easy_strerror(res));
228229
if (res != CURLcode::CURLE_OK) {
229230
string error = curl_easy_strerror(res);
230-
throw IOException("Curl Request to '%s' failed with error: '%s'", url, error);
231+
throw HTTPException("Curl Request to '%s' failed with error: '%s'", url, error);
231232
}
232233
return readBuffer;
233234
}

src/common/iceberg.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ unique_ptr<SnapshotParseInfo> IcebergSnapshot::GetParseInfo(yyjson_doc &metadata
6464
} else {
6565
auto schema = yyjson_obj_get(root, "schema");
6666
if (!schema) {
67-
throw IOException("Neither a valid schema or schemas field was found");
67+
throw InvalidInputException("Neither a valid schema or schemas field was found");
6868
}
6969
auto found_schema_id = IcebergUtils::TryGetNumFromObject(schema, "schema-id");
7070
info.schemas.push_back(schema);
@@ -103,7 +103,7 @@ IcebergSnapshot IcebergSnapshot::GetSnapshotById(const string &path, FileSystem
103103
auto snapshot = FindSnapshotByIdInternal(info->snapshots, snapshot_id);
104104

105105
if (!snapshot) {
106-
throw IOException("Could not find snapshot with id " + to_string(snapshot_id));
106+
throw InvalidInputException("Could not find snapshot with id " + to_string(snapshot_id));
107107
}
108108

109109
return ParseSnapShot(snapshot, info->iceberg_version, info->schema_id, info->schemas, options);
@@ -115,7 +115,7 @@ IcebergSnapshot IcebergSnapshot::GetSnapshotByTimestamp(const string &path, File
115115
auto snapshot = FindSnapshotByIdTimestampInternal(info->snapshots, timestamp);
116116

117117
if (!snapshot) {
118-
throw IOException("Could not find latest snapshots for timestamp " + Timestamp::ToString(timestamp));
118+
throw InvalidInputException("Could not find latest snapshots for timestamp " + Timestamp::ToString(timestamp));
119119
}
120120

121121
return ParseSnapShot(snapshot, info->iceberg_version, info->schema_id, info->schemas, options);
@@ -138,7 +138,7 @@ static string GenerateMetaDataUrl(FileSystem &fs, const string &meta_path, strin
138138
}
139139
}
140140

141-
throw IOException(
141+
throw InvalidInputException(
142142
"Iceberg metadata file not found for table version '%s' using '%s' compression and format(s): '%s'",
143143
table_version, options.metadata_compression_codec, options.version_name_format);
144144
}
@@ -171,7 +171,7 @@ string IcebergSnapshot::GetMetaDataPath(ClientContext &context, const string &pa
171171
}
172172
if (!UnsafeVersionGuessingEnabled(context)) {
173173
// Make sure we're allowed to guess versions
174-
throw IOException(
174+
throw InvalidInputException(
175175
"Failed to read iceberg table. No version was provided and no version-hint could be found, globbing the "
176176
"filesystem to locate the latest version is disabled by default as this is considered unsafe and could "
177177
"result in reading uncommitted data. To enable this use 'SET %s = true;'",
@@ -195,7 +195,7 @@ IcebergSnapshot IcebergSnapshot::ParseSnapShot(yyjson_val *snapshot, idx_t icebe
195195
if (snapshot) {
196196
auto snapshot_tag = yyjson_get_type(snapshot);
197197
if (snapshot_tag != YYJSON_TYPE_OBJ) {
198-
throw IOException("Invalid snapshot field found parsing iceberg metadata.json");
198+
throw InvalidInputException("Invalid snapshot field found parsing iceberg metadata.json");
199199
}
200200
ret.metadata_compression_codec = options.metadata_compression_codec;
201201
if (iceberg_format_version == 1) {
@@ -226,9 +226,9 @@ string IcebergSnapshot::GetTableVersionFromHint(const string &meta_path, FileSys
226226
try {
227227
return version_file_content;
228228
} catch (std::invalid_argument &e) {
229-
throw IOException("Iceberg version hint file contains invalid value");
229+
throw InvalidInputException("Iceberg version hint file contains invalid value");
230230
} catch (std::out_of_range &e) {
231-
throw IOException("Iceberg version hint file contains invalid value");
231+
throw InvalidInputException("Iceberg version hint file contains invalid value");
232232
}
233233
}
234234

@@ -262,8 +262,8 @@ string IcebergSnapshot::GuessTableVersion(const string &meta_path, FileSystem &f
262262
}
263263
}
264264

265-
throw IOException("Could not guess Iceberg table version using '%s' compression and format(s): '%s'",
266-
metadata_compression_codec, version_format);
265+
throw InvalidInputException("Could not guess Iceberg table version using '%s' compression and format(s): '%s'",
266+
metadata_compression_codec, version_format);
267267
}
268268

269269
string IcebergSnapshot::PickTableVersion(vector<string> &found_metadata, string &version_pattern, string &glob) {

src/common/schema.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,13 @@ static LogicalType ParseComplexType(yyjson_val *type) {
6363
if (type_str == "map") {
6464
return ParseMap(type);
6565
}
66-
throw IOException("Invalid field found while parsing field: type");
66+
throw InvalidInputException("Invalid field found while parsing field: type");
6767
}
6868

6969
static LogicalType ParseType(yyjson_val *type) {
7070
auto val = yyjson_obj_get(type, "type");
7171
if (!val) {
72-
throw IOException("Invalid field found while parsing field: type");
72+
throw InvalidInputException("Invalid field found while parsing field: type");
7373
}
7474
return ParseTypeValue(val);
7575
}
@@ -79,7 +79,7 @@ static LogicalType ParseTypeValue(yyjson_val *val) {
7979
return ParseComplexType(val);
8080
}
8181
if (yyjson_get_type(val) != YYJSON_TYPE_STR) {
82-
throw IOException("Invalid field found while parsing field: type");
82+
throw InvalidInputException("Invalid field found while parsing field: type");
8383
}
8484
string type_str = yyjson_get_str(val);
8585

@@ -136,7 +136,7 @@ static LogicalType ParseTypeValue(yyjson_val *val) {
136136
auto scale = std::stoi(digits[1]);
137137
return LogicalType::DECIMAL(width, scale);
138138
}
139-
throw IOException("Encountered an unrecognized type in JSON schema: \"%s\"", type_str);
139+
throw InvalidInputException("Encountered an unrecognized type in JSON schema: \"%s\"", type_str);
140140
}
141141

142142
IcebergColumnDefinition IcebergColumnDefinition::ParseFromJson(yyjson_val *val) {
@@ -155,7 +155,7 @@ static vector<IcebergColumnDefinition> ParseSchemaFromJson(yyjson_val *schema_js
155155
// Assert that the top level 'type' is a struct
156156
auto type_str = IcebergUtils::TryGetStrFromObject(schema_json, "type");
157157
if (type_str != "struct") {
158-
throw IOException("Schema in JSON Metadata is invalid");
158+
throw InvalidInputException("Schema in JSON Metadata is invalid");
159159
}
160160
D_ASSERT(yyjson_get_type(schema_json) == YYJSON_TYPE_OBJ);
161161
D_ASSERT(IcebergUtils::TryGetStrFromObject(schema_json, "type") == "struct");
@@ -180,7 +180,7 @@ vector<IcebergColumnDefinition> IcebergSnapshot::ParseSchema(vector<yyjson_val *
180180
}
181181
}
182182

183-
throw IOException("Iceberg schema with schema id " + to_string(schema_id) + " was not found!");
183+
throw InvalidInputException("Iceberg schema with schema id " + to_string(schema_id) + " was not found!");
184184
}
185185

186186
} // namespace duckdb

src/common/utils.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,29 +32,29 @@ string IcebergUtils::GetFullPath(const string &iceberg_path, const string &relat
3232
return fs.JoinPath(iceberg_path, relative_file_path.substr(found + 1));
3333
}
3434

35-
throw IOException("Did not recognize iceberg path");
35+
throw InvalidInputException("Did not recognize iceberg path");
3636
}
3737

3838
uint64_t IcebergUtils::TryGetNumFromObject(yyjson_val *obj, const string &field) {
3939
auto val = yyjson_obj_getn(obj, field.c_str(), field.size());
4040
if (!val || yyjson_get_type(val) != YYJSON_TYPE_NUM) {
41-
throw IOException("Invalid field found while parsing field: " + field);
41+
throw InvalidInputException("Invalid field found while parsing field: " + field);
4242
}
4343
return yyjson_get_uint(val);
4444
}
4545

4646
bool IcebergUtils::TryGetBoolFromObject(yyjson_val *obj, const string &field) {
4747
auto val = yyjson_obj_getn(obj, field.c_str(), field.size());
4848
if (!val || yyjson_get_type(val) != YYJSON_TYPE_BOOL) {
49-
throw IOException("Invalid field found while parsing field: " + field);
49+
throw InvalidInputException("Invalid field found while parsing field: " + field);
5050
}
5151
return yyjson_get_bool(val);
5252
}
5353

5454
string IcebergUtils::TryGetStrFromObject(yyjson_val *obj, const string &field) {
5555
auto val = yyjson_obj_getn(obj, field.c_str(), field.size());
5656
if (!val || yyjson_get_type(val) != YYJSON_TYPE_STR) {
57-
throw IOException("Invalid field found while parsing field: " + field);
57+
throw InvalidInputException("Invalid field found while parsing field: " + field);
5858
}
5959
return yyjson_get_str(val);
6060
}
@@ -67,7 +67,7 @@ static TYPE TemplatedTryGetYYJson(yyjson_val *obj, const string &field, TYPE def
6767
} else if (!fail_on_missing) {
6868
return default_val;
6969
}
70-
throw IOException("Invalid field found while parsing field: " + field);
70+
throw InvalidInputException("Invalid field found while parsing field: " + field);
7171
}
7272

7373
uint64_t IcebergUtils::TryGetNumFromObject(yyjson_val *obj, const string &field, bool fail_on_missing,

src/iceberg_extension.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,14 @@ static bool SanityCheckGlueWarehouse(string warehouse) {
6464
auto bucket_sep = warehouse.find_first_of('/');
6565
bool bucket_sep_correct = bucket_sep == 28;
6666
if (!account_id_correct) {
67-
throw IOException("Invalid Glue Catalog Format: '" + warehouse + "'. Expect 12 digits for account_id.");
67+
throw InvalidInputException("Invalid Glue Catalog Format: '" + warehouse +
68+
"'. Expect 12 digits for account_id.");
6869
}
6970
if (bucket_sep_correct) {
7071
return true;
7172
}
72-
throw IOException("Invalid Glue Catalog Format: '" + warehouse +
73-
"'. Expected '<account_id>:s3tablescatalog/<bucket>");
73+
throw InvalidInputException("Invalid Glue Catalog Format: '" + warehouse +
74+
"'. Expected '<account_id>:s3tablescatalog/<bucket>");
7475
}
7576

7677
static unique_ptr<Catalog> IcebergCatalogAttach(StorageExtensionInfo *storage_info, ClientContext &context,
@@ -120,8 +121,8 @@ static unique_ptr<Catalog> IcebergCatalogAttach(StorageExtensionInfo *storage_in
120121
auto region = kv_secret.TryGetValue("region");
121122

122123
if (region.IsNull()) {
123-
throw IOException("Assumed catalog secret " + secret_entry->secret->GetName() + " for catalog " + name +
124-
" does not have a region");
124+
throw InvalidInputException("Assumed catalog secret " + secret_entry->secret->GetName() + " for catalog " +
125+
name + " does not have a region");
125126
}
126127
switch (catalog_type) {
127128
case ICEBERG_CATALOG_TYPE::AWS_S3TABLES: {
@@ -137,7 +138,7 @@ static unique_ptr<Catalog> IcebergCatalogAttach(StorageExtensionInfo *storage_in
137138
SanityCheckGlueWarehouse(warehouse);
138139
break;
139140
default:
140-
throw IOException("Unsupported AWS catalog type");
141+
throw NotImplementedException("Unsupported AWS catalog type");
141142
}
142143

143144
auto catalog_host = service + "." + region.ToString() + ".amazonaws.com";
@@ -149,10 +150,11 @@ static unique_ptr<Catalog> IcebergCatalogAttach(StorageExtensionInfo *storage_in
149150

150151
// Check no endpoint type has been passed.
151152
if (!endpoint_type.empty()) {
152-
throw IOException("Unrecognized endpoint point: %s. Expected either S3_TABLES or GLUE", endpoint_type);
153+
throw InvalidInputException("Unrecognized endpoint point: %s. Expected either S3_TABLES or GLUE",
154+
endpoint_type);
153155
}
154156
if (endpoint_type.empty() && endpoint.empty()) {
155-
throw IOException("No endpoint type or endpoint provided");
157+
throw InvalidInputException("No endpoint type or endpoint provided");
156158
}
157159

158160
catalog_type = ICEBERG_CATALOG_TYPE::OTHER;
@@ -162,7 +164,7 @@ static unique_ptr<Catalog> IcebergCatalogAttach(StorageExtensionInfo *storage_in
162164
// if no secret is referenced, this throw
163165
auto secret_entry = IRCatalog::GetSecret(context, secret_name);
164166
if (!secret_entry) {
165-
throw IOException("No secret found to use with catalog " + name);
167+
throw InvalidConfigurationException("No secret found to use with catalog " + name);
166168
}
167169
// secret found - read data
168170
const auto &kv_secret = dynamic_cast<const KeyValueSecret &>(*secret_entry->secret);

src/iceberg_functions/iceberg_multi_file_reader.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ void IcebergMultiFileReader::CreateColumnMapping(const string &file_name,
313313
// Lookup the required column in the local map
314314
auto entry = name_map.find("file_row_number");
315315
if (entry == name_map.end()) {
316-
throw IOException("Failed to find the file_row_number column");
316+
throw InvalidInputException("Failed to find the file_row_number column");
317317
}
318318

319319
// Register the column to be scanned from this file

src/include/iceberg_types.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ static string IcebergManifestContentTypeToString(IcebergManifestContentType type
2727
case IcebergManifestContentType::DELETE:
2828
return "DELETE";
2929
default:
30-
throw IOException("Invalid Manifest Content Type");
30+
throw InvalidInputException("Invalid Manifest Content Type");
3131
}
3232
}
3333

@@ -42,7 +42,7 @@ static string IcebergManifestEntryStatusTypeToString(IcebergManifestEntryStatusT
4242
case IcebergManifestEntryStatusType::DELETED:
4343
return "DELETED";
4444
default:
45-
throw IOException("Invalid matifest entry type");
45+
throw InvalidInputException("Invalid matifest entry type");
4646
}
4747
}
4848

@@ -57,7 +57,7 @@ static string IcebergManifestEntryContentTypeToString(IcebergManifestEntryConten
5757
case IcebergManifestEntryContentType::EQUALITY_DELETES:
5858
return "EQUALITY_DELETES";
5959
default:
60-
throw IOException("Invalid Manifest Entry Content Type");
60+
throw InvalidInputException("Invalid Manifest Entry Content Type");
6161
}
6262
}
6363

src/storage/irc_catalog.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,14 @@ unique_ptr<SecretEntry> IRCatalog::GetSecret(ClientContext &context, const strin
168168
if (!secret_entry) {
169169
auto secret_match = context.db->GetSecretManager().LookupSecret(transaction, "s3://", "s3");
170170
if (!secret_match.HasMatch()) {
171-
throw IOException("Failed to find a secret and no explicit secret was passed!");
171+
throw InvalidConfigurationException("Failed to find a secret and no explicit secret was passed!");
172172
}
173173
secret_entry = std::move(secret_match.secret_entry);
174174
}
175175
if (secret_entry) {
176176
return secret_entry;
177177
}
178-
throw IOException("Could not find valid Iceberg secret");
178+
throw InvalidConfigurationException("Could not find valid Iceberg secret");
179179
}
180180

181181
unique_ptr<PhysicalOperator> IRCatalog::PlanInsert(ClientContext &context, LogicalInsert &op,

0 commit comments

Comments
 (0)