faulty SQLGetDiagRec() call, unicode error, temporary workaround v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Tue, 02 Jun 2020 23:31:55 +0200
branchv_0
changeset 44 ec9694f3b343
parent 43 7f396cdb9628
child 45 225e294ad1db
faulty SQLGetDiagRec() call, unicode error, temporary workaround
src/SqlException.cpp
--- a/src/SqlException.cpp	Tue Jun 02 20:57:12 2020 +0200
+++ b/src/SqlException.cpp	Tue Jun 02 23:31:55 2020 +0200
@@ -42,7 +42,17 @@
 	SQLINTEGER sqlcode;
 	SQLSMALLINT length;
 	for (SQLSMALLINT i = 1; SQLGetDiagRec(handleType, handle, i, sqlstate, &sqlcode, buffer, SQL_MAX_MESSAGE_LENGTH + 1, &length) == SQL_SUCCESS; i++) {
+		for (size_t i = 0; i < sizeof (buffer); i++) if (buffer[i] > 126 || buffer[i] == '\r') buffer[i] = '?'; // keep only ASCII characters and avoid CR which breaks the output
 		diagnostics.push_back({convertor.from_bytes((char*) sqlstate), sqlcode, convertor.from_bytes((char*) buffer)});
+		// FIXME: decoding fails is error message contains unicode characters – exception is thrown:
+		// terminate called after throwing an instance of 'std::range_error'
+		//   what():  wstring_convert::from_bytes
+		// Exception can be avoided by:
+		//   std::wstring_convert < std::codecvt_utf8<wchar_t>> convertor("", L"XXX Unable to decode error message from SQLGetDiagRec()");
+		// but actual error message is then lost.
+		// So as a workaround we keep only ASCII characters.
+		// It seems that we sometimes get valid ISO-8859-2 or ISO-8859-1 encoded messages even if our platform encoding is UTF-8.
+
 	}
 	if (freeHandle) OdbcCommon::freeHandle(handleType, handle);
 }