Skip to content

Commit b457c8f

Browse files
committed
feat(network): report error messages received from sync endpoints. This allows returning meaningful errors to the client, such as when the device limit is exceeded.
1 parent 360a057 commit b457c8f

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/network.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -136,13 +136,13 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
136136
size_t blen = 0;
137137
struct curl_slist* headers = NULL;
138138
char errbuf[CURL_ERROR_SIZE] = {0};
139-
139+
long response_code = 0;
140+
140141
CURL *curl = curl_easy_init();
141142
if (!curl) return (NETWORK_RESULT){CLOUDSYNC_NETWORK_ERROR, NULL, 0, NULL, NULL};
142143

143144
// a buffer to store errors in
144145
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
145-
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
146146

147147
CURLcode rc = curl_easy_setopt(curl, CURLOPT_URL, endpoint);
148148
if (rc != CURLE_OK) goto cleanup;
@@ -184,6 +184,7 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
184184

185185
// curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
186186
rc = curl_easy_perform(curl);
187+
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
187188
if (rc == CURLE_OK) {
188189
buffer = netdata.buffer;
189190
blen = netdata.bused;
@@ -197,14 +198,14 @@ NETWORK_RESULT network_receive_buffer (network_data *data, const char *endpoint,
197198

198199
// build result
199200
NETWORK_RESULT result = {0, NULL, 0, NULL, NULL};
200-
if (rc == CURLE_OK) {
201+
if (rc == CURLE_OK && response_code < 400) {
201202
result.code = (buffer && blen) ? CLOUDSYNC_NETWORK_BUFFER : CLOUDSYNC_NETWORK_OK;
202203
result.buffer = buffer;
203204
result.blen = blen;
204205
} else {
205206
result.code = CLOUDSYNC_NETWORK_ERROR;
206-
result.buffer = (errbuf[0]) ? cloudsync_string_dup(errbuf, false) : NULL;
207-
result.blen = rc;
207+
result.buffer = buffer ? buffer : (errbuf[0]) ? cloudsync_string_dup(errbuf, false) : NULL;
208+
result.blen = buffer ? blen : rc;
208209
}
209210

210211
return result;
@@ -549,7 +550,7 @@ bool network_compute_endpoints (sqlite3_context *context, network_data *data, co
549550

550551
void network_result_to_sqlite_error (sqlite3_context *context, NETWORK_RESULT res, const char *default_error_message) {
551552
sqlite3_result_error(context, ((res.code == CLOUDSYNC_NETWORK_ERROR) && (res.buffer)) ? res.buffer : default_error_message, -1);
552-
sqlite3_result_error_code(context, ((res.code == CLOUDSYNC_NETWORK_ERROR) && (res.blen)) ? (int)res.blen : SQLITE_ERROR);
553+
sqlite3_result_error_code(context, SQLITE_ERROR);
553554
network_result_cleanup(&res);
554555
}
555556

@@ -685,19 +686,19 @@ void cloudsync_network_has_unsent_changes (sqlite3_context *context, int argc, s
685686
sqlite3_result_int(context, (sent_db_version < last_local_change));
686687
}
687688

688-
void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3_value **argv) {
689+
int cloudsync_network_send_changes_internal (sqlite3_context *context, int argc, sqlite3_value **argv) {
689690
DEBUG_FUNCTION("cloudsync_network_send_changes");
690691

691692
network_data *data = (network_data *)cloudsync_get_auxdata(context);
692-
if (!data) {sqlite3_result_error(context, "Unable to retrieve CloudSync context.", -1); return;}
693+
if (!data) {sqlite3_result_error(context, "Unable to retrieve CloudSync context.", -1); return SQLITE_ERROR;}
693694

694695
sqlite3 *db = sqlite3_context_db_handle(context);
695696

696697
int db_version = dbutils_settings_get_int_value(db, CLOUDSYNC_KEY_SEND_DBVERSION);
697-
if (db_version<0) {sqlite3_result_error(context, "Unable to retrieve db_version.", -1); return;}
698+
if (db_version<0) {sqlite3_result_error(context, "Unable to retrieve db_version.", -1); return SQLITE_ERROR;}
698699

699700
int seq = dbutils_settings_get_int_value(db, CLOUDSYNC_KEY_SEND_SEQ);
700-
if (seq<0) {sqlite3_result_error(context, "Unable to retrieve seq.", -1); return;}
701+
if (seq<0) {sqlite3_result_error(context, "Unable to retrieve seq.", -1); return SQLITE_ERROR;}
701702

702703
// retrieve BLOB
703704
char sql[1024];
@@ -711,24 +712,24 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
711712
if (rc != SQLITE_OK) {
712713
sqlite3_result_error(context, "cloudsync_network_send_changes unable to get changes", -1);
713714
sqlite3_result_error_code(context, rc);
714-
return;
715+
return rc;
715716
}
716717

717718
// exit if there are no data to send
718-
if (blob == NULL || blob_size == 0) return;
719+
if (blob == NULL || blob_size == 0) return SQLITE_OK;
719720

720721
NETWORK_RESULT res = network_receive_buffer(data, data->upload_endpoint, data->authentication, true, false, NULL, CLOUDSYNC_HEADER_SQLITECLOUD);
721722
if (res.code != CLOUDSYNC_NETWORK_BUFFER) {
722723
network_result_to_sqlite_error(context, res, "cloudsync_network_send_changes unable to receive upload URL");
723-
return;
724+
return SQLITE_ERROR;
724725
}
725726

726727
const char *s3_url = res.buffer;
727728
bool sent = network_send_buffer(data, s3_url, NULL, blob, blob_size);
728729
cloudsync_memory_free(blob);
729730
if (sent == false) {
730731
network_result_to_sqlite_error(context, res, "cloudsync_network_send_changes unable to upload BLOB changes to remote host.");
731-
return;
732+
return SQLITE_ERROR;
732733
}
733734

734735
char json_payload[2024];
@@ -741,7 +742,7 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
741742
res = network_receive_buffer(data, data->upload_endpoint, data->authentication, true, true, json_payload, CLOUDSYNC_HEADER_SQLITECLOUD);
742743
if (res.code != CLOUDSYNC_NETWORK_OK) {
743744
network_result_to_sqlite_error(context, res, "cloudsync_network_send_changes unable to notify BLOB upload to remote host.");
744-
return;
745+
return SQLITE_ERROR;
745746
}
746747

747748
char buf[256];
@@ -755,6 +756,13 @@ void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3
755756
}
756757

757758
network_result_cleanup(&res);
759+
return SQLITE_OK;
760+
}
761+
762+
void cloudsync_network_send_changes (sqlite3_context *context, int argc, sqlite3_value **argv) {
763+
DEBUG_FUNCTION("cloudsync_network_send_changes");
764+
765+
cloudsync_network_send_changes_internal(context, argc, argv);
758766
}
759767

760768
int cloudsync_network_check_internal(sqlite3_context *context) {
@@ -786,7 +794,8 @@ int cloudsync_network_check_internal(sqlite3_context *context) {
786794
}
787795

788796
void cloudsync_network_sync (sqlite3_context *context, int wait_ms, int max_retries) {
789-
cloudsync_network_send_changes(context, 0, NULL);
797+
int rc = cloudsync_network_send_changes_internal(context, 0, NULL);
798+
if (rc != SQLITE_OK) return;
790799

791800
int ntries = 0;
792801
int nrows = 0;

0 commit comments

Comments
 (0)