Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Set HResult property of SQLiteException based on the SQLite core library error code. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a4575fc8e709244447d6cf4c2bcb16cd |
User & Date: | mistachkin 2018-02-26 17:32:15.079 |
Context
2018-02-26
| ||
17:32 | Update version history docs. check-in: 2d61f3fabf user: mistachkin tags: trunk | |
17:32 | Set HResult property of SQLiteException based on the SQLite core library error code. check-in: a4575fc8e7 user: mistachkin tags: trunk | |
17:25 | Add more database connection configuration options for the sqlite3_db_config() interface. check-in: b7ba6996c1 user: mistachkin tags: trunk | |
Changes
Changes to System.Data.SQLite/SQLiteException.cs.
︙ | ︙ | |||
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | #if !PLATFORM_COMPACTFRAMEWORK [Serializable()] public sealed class SQLiteException : DbException, ISerializable #else public sealed class SQLiteException : Exception #endif { private SQLiteErrorCode _errorCode; /////////////////////////////////////////////////////////////////////////// #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Private constructor for use with serialization. /// </summary> /// <param name="info"> /// Holds the serialized object data about the exception being thrown. /// </param> /// <param name="context"> /// Contains contextual information about the source or destination. /// </param> private SQLiteException(SerializationInfo info, StreamingContext context) : base(info, context) { _errorCode = (SQLiteErrorCode)info.GetInt32("errorCode"); } #endif /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor for generating a SQLite exception given the error /// code and message. /// </summary> /// <param name="errorCode"> /// The SQLite return code to report. /// </param> /// <param name="message"> /// Message text to go along with the return code message text. /// </param> public SQLiteException(SQLiteErrorCode errorCode, string message) : base(GetStockErrorMessage(errorCode, message)) { _errorCode = errorCode; } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor that uses the base class constructor for the error /// message. /// </summary> /// <param name="message">Error message text.</param> public SQLiteException(string message) : this(SQLiteErrorCode.Unknown, message) { } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor that uses the default base class constructor. /// </summary> public SQLiteException() { } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor that uses the base class constructor for the error /// message and inner exception. /// </summary> /// <param name="message">Error message text.</param> /// <param name="innerException">The original (inner) exception.</param> public SQLiteException(string message, Exception innerException) : base(message, innerException) { } /////////////////////////////////////////////////////////////////////////// #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Adds extra information to the serialized object data specific to this | > > > > > > > > > > > > > > > > > > | 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | #if !PLATFORM_COMPACTFRAMEWORK [Serializable()] public sealed class SQLiteException : DbException, ISerializable #else public sealed class SQLiteException : Exception #endif { #region Private Constants /// <summary> /// This value was copied from the "WinError.h" file included with the /// Platform SDK for Windows 10. /// </summary> private const int FACILITY_SQLITE = 1967; #endregion /////////////////////////////////////////////////////////////////////////// private SQLiteErrorCode _errorCode; /////////////////////////////////////////////////////////////////////////// #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Private constructor for use with serialization. /// </summary> /// <param name="info"> /// Holds the serialized object data about the exception being thrown. /// </param> /// <param name="context"> /// Contains contextual information about the source or destination. /// </param> private SQLiteException(SerializationInfo info, StreamingContext context) : base(info, context) { _errorCode = (SQLiteErrorCode)info.GetInt32("errorCode"); Initialize(); } #endif /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor for generating a SQLite exception given the error /// code and message. /// </summary> /// <param name="errorCode"> /// The SQLite return code to report. /// </param> /// <param name="message"> /// Message text to go along with the return code message text. /// </param> public SQLiteException(SQLiteErrorCode errorCode, string message) : base(GetStockErrorMessage(errorCode, message)) { _errorCode = errorCode; Initialize(); } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor that uses the base class constructor for the error /// message. /// </summary> /// <param name="message">Error message text.</param> public SQLiteException(string message) : this(SQLiteErrorCode.Unknown, message) { // do nothing. } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor that uses the default base class constructor. /// </summary> public SQLiteException() : base() { Initialize(); } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Public constructor that uses the base class constructor for the error /// message and inner exception. /// </summary> /// <param name="message">Error message text.</param> /// <param name="innerException">The original (inner) exception.</param> public SQLiteException(string message, Exception innerException) : base(message, innerException) { Initialize(); } /////////////////////////////////////////////////////////////////////////// #if !PLATFORM_COMPACTFRAMEWORK /// <summary> /// Adds extra information to the serialized object data specific to this |
︙ | ︙ | |||
153 154 155 156 157 158 159 160 161 162 163 164 165 166 | public override int ErrorCode #else public int ErrorCode #endif { get { return (int)_errorCode; } } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns the error message for the specified SQLite return code. /// </summary> /// <param name="errorCode">The SQLite return code.</param> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 | public override int ErrorCode #else public int ErrorCode #endif { get { return (int)_errorCode; } } /////////////////////////////////////////////////////////////////////////// /// <summary> /// This method performs extra initialization tasks. It may be called by /// any of the constructors of this class. It must not throw exceptions. /// </summary> private void Initialize() { if (HResult == unchecked((int)0x80004005)) /* E_FAIL */ { int? localHResult = GetHResultForErrorCode(ResultCode); if (localHResult != null) HResult = (int)localHResult; } } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Maps a Win32 error code to an HRESULT. /// </summary> /// <param name="errorCode"> /// The specified Win32 error code. It must be within the range of zero /// (0) to 0xFFFF (65535). /// </param> /// <param name="success"> /// Non-zero if the HRESULT should indicate success; otherwise, zero. /// </param> /// <returns> /// The integer value of the HRESULT. /// </returns> private static int MakeHResult( int errorCode, bool success ) { return (errorCode & 0xFFFF) | FACILITY_SQLITE | (success ? 0 : unchecked((int)0x80000000)); } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Attempts to map the specified <see cref="SQLiteErrorCode" /> onto an /// existing HRESULT -OR- a Win32 error code wrapped in an HRESULT. The /// mappings may not have perfectly matching semantics; however, they do /// have the benefit of being unique within the context of this exception /// type. /// </summary> /// <param name="errorCode"> /// The <see cref="SQLiteErrorCode" /> to map. /// </param> /// <returns> /// The integer HRESULT value -OR- null if there is no known mapping. /// </returns> private static int? GetHResultForErrorCode( SQLiteErrorCode errorCode ) { switch (errorCode & SQLiteErrorCode.NonExtendedMask) { case SQLiteErrorCode.Ok: { return 0; /* S_OK */ } case SQLiteErrorCode.Error: { return MakeHResult(0x0057, false); /* E_INVALIDARG */ } case SQLiteErrorCode.Internal: { return unchecked((int)0x8000FFFF); /* E_UNEXPECTED */ } case SQLiteErrorCode.Perm: { return MakeHResult(0x0005, false); /* E_ACCESSDENIED */ } case SQLiteErrorCode.Abort: { return unchecked((int)0x80004004); /* E_ABORT */ } case SQLiteErrorCode.Busy: { return MakeHResult(0x00AA, false); /* ERROR_BUSY */ } case SQLiteErrorCode.Locked: { return MakeHResult(0x00D4, false); /* ERROR_LOCKED */ } case SQLiteErrorCode.NoMem: { return MakeHResult(0x000E, false); /* E_OUTOFMEMORY */ } case SQLiteErrorCode.ReadOnly: { return MakeHResult(0x1779, false); /* ERROR_FILE_READ_ONLY */ } case SQLiteErrorCode.Interrupt: { return MakeHResult(0x04C7, false); /* ERROR_CANCELLED */ } case SQLiteErrorCode.IoErr: { return MakeHResult(0x045D, false); /* ERROR_IO_DEVICE */ } case SQLiteErrorCode.Corrupt: { return MakeHResult(0x054E, false); /* ERROR_INTERNAL_DB_CORRUPTION */ } case SQLiteErrorCode.NotFound: { return MakeHResult(0x0032, false); /* ERROR_NOT_SUPPORTED */ } case SQLiteErrorCode.Full: { return MakeHResult(0x0070, false); /* ERROR_DISK_FULL */ } case SQLiteErrorCode.CantOpen: { return MakeHResult(0x03F3, false); /* ERROR_CANTOPEN */ } case SQLiteErrorCode.Protocol: { return MakeHResult(0x05B4, false); /* ERROR_TIMEOUT */ } case SQLiteErrorCode.Empty: { return MakeHResult(0x10D2, false); /* ERROR_EMPTY */ } case SQLiteErrorCode.Schema: { return MakeHResult(0x078B, false); /* ERROR_CONTEXT_EXPIRED */ } case SQLiteErrorCode.TooBig: { return unchecked((int)0x800288C5); /* TYPE_E_SIZETOOBIG */ } case SQLiteErrorCode.Constraint: { return MakeHResult(0x202F, false); /* ERROR_DS_CONSTRAINT_VIOLATION */ } case SQLiteErrorCode.Mismatch: { return MakeHResult(0x065D, false); /* ERROR_DATATYPE_MISMATCH */ } case SQLiteErrorCode.Misuse: { return MakeHResult(0x0649, false); /* ERROR_INVALID_HANDLE_STATE */ } case SQLiteErrorCode.NoLfs: { return MakeHResult(0x0646, false); /* ERROR_UNKNOWN_FEATURE */ } case SQLiteErrorCode.Auth: { return MakeHResult(0x078F, false); /* ERROR_AUTHENTICATION_FIREWALL_FAILED */ } case SQLiteErrorCode.Format: { return MakeHResult(0x000B, false); /* ERROR_BAD_FORMAT */ } case SQLiteErrorCode.Range: { return unchecked((int)0x80028CA1); /* TYPE_E_OUTOFBOUNDS */ } case SQLiteErrorCode.NotADb: { return MakeHResult(0x0570, false); /* ERROR_FILE_CORRUPT */ } case SQLiteErrorCode.Notice: case SQLiteErrorCode.Warning: case SQLiteErrorCode.Row: case SQLiteErrorCode.Done: { // // NOTE: These result codes are not errors, per se; // therefore, mask off all HRESULT bits that // are not part of the "code" portion (e.g. // the severity, facility, etc). This will // have the effect of creating an HRESULT // that indicates success, while (hopefully) // preserving the specified result code. At // the time this method was written (2018-02), // no SQLite result codes were outside of the // supported range for HRESULT codes (e.g. // 0x0000 to 0xFFFF, inclusive), which made // the following masking operation a harmless // NOOP. // return MakeHResult((int)errorCode, true); } } return null; } /////////////////////////////////////////////////////////////////////////// /// <summary> /// Returns the error message for the specified SQLite return code. /// </summary> /// <param name="errorCode">The SQLite return code.</param> |
︙ | ︙ |
Changes to Tests/tkt-53962f9eff.eagle.
︙ | ︙ | |||
28 29 30 31 32 33 34 | System.Data.SQLite.SQLiteException $errCode "ioerr message."] normalizeExceptionMessage [$exception ToString] } -cleanup { unset -nocomplain exception errCode } -constraints {eagle command.object SQLite System.Data.SQLite} -match \ regexp -result {^code = IoErr_Delete_NoEnt \(5898\), message =\ | | | | | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | System.Data.SQLite.SQLiteException $errCode "ioerr message."] normalizeExceptionMessage [$exception ToString] } -cleanup { unset -nocomplain exception errCode } -constraints {eagle command.object SQLite System.Data.SQLite} -match \ regexp -result {^code = IoErr_Delete_NoEnt \(5898\), message =\ System\.Data\.SQLite\.SQLiteException(?: \(0x8[0-9A-Fa-f]{7}\))?: disk I/O\ error ==> ioerr message\.$}} ############################################################################### runTest {test tkt-53962f9eff-1.2 {SQLiteException ToString Ok} -body { set errCode [object invoke -create Enum Parse \ System.Data.SQLite.SQLiteErrorCode Ok_Load_Permanently false] set exception [object create -alias \ System.Data.SQLite.SQLiteException $errCode "ok message."] normalizeExceptionMessage [$exception ToString] } -cleanup { unset -nocomplain exception errCode } -constraints {eagle command.object SQLite System.Data.SQLite} -match \ regexp -result {^code = Ok_Load_Permanently \(256\), message =\ System\.Data\.SQLite\.SQLiteException(?: \(0x0[0-9A-Fa-f]{7}\))?: not an\ error ==> ok message.$}} ############################################################################### runTest {test tkt-53962f9eff-1.3 {SQLiteException ToString unknown} -body { set errCode [object invoke -create Enum Parse \ System.Data.SQLite.SQLiteErrorCode 999 false] set exception [object create -alias \ System.Data.SQLite.SQLiteException $errCode "unknown message."] normalizeExceptionMessage [$exception ToString] } -cleanup { unset -nocomplain exception errCode } -constraints {eagle command.object SQLite System.Data.SQLite} -match \ regexp -result {^code = 999 \(999\), message =\ System\.Data\.SQLite\.SQLiteException(?: \(0x8[0-9A-Fa-f]{7}\))?: unknown\ error ==> unknown message\.$}} ############################################################################### runSQLiteTestEpilogue runTestEpilogue |
Changes to lib/System.Data.SQLite/common.eagle.
︙ | ︙ | |||
2399 2400 2401 2402 2403 2404 2405 | proc extractSystemDataSQLiteExceptionMessage { value } { # # NOTE: If the string conforms to format of the normal exception # error strings, extract and return only the error message # portion itself. # set patterns [list \ | | > | 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 | proc extractSystemDataSQLiteExceptionMessage { value } { # # NOTE: If the string conforms to format of the normal exception # error strings, extract and return only the error message # portion itself. # set patterns [list \ {System\.Data\.SQLite\.SQLiteException \(0x(?:0|8)[0-9A-Fa-f]{7}\):\ (.+?) (?: )?at} \ {System\.Data\.SQLite\.SQLiteException: (.+?) (?: )?at} \ {Eagle\._Components\.Public\.ScriptException: (.+?) (?: )?at}] foreach pattern $patterns { if {[regexp -- $pattern $value dummy message]} then { set message [string map [list \r\n \n] [string trim $message]] set lines [split $message \n] |
︙ | ︙ |