github.com/snowflakedb/gosnowflake@v1.9.0/errors.go (about) 1 // Copyright (c) 2017-2022 Snowflake Computing Inc. All rights reserved. 2 3 package gosnowflake 4 5 import ( 6 "fmt" 7 "runtime/debug" 8 "strconv" 9 "time" 10 ) 11 12 // SnowflakeError is a error type including various Snowflake specific information. 13 type SnowflakeError struct { 14 Number int 15 SQLState string 16 QueryID string 17 Message string 18 MessageArgs []interface{} 19 IncludeQueryID bool // TODO: populate this in connection 20 } 21 22 func (se *SnowflakeError) Error() string { 23 message := se.Message 24 if len(se.MessageArgs) > 0 { 25 message = fmt.Sprintf(se.Message, se.MessageArgs...) 26 } 27 if se.SQLState != "" { 28 if se.IncludeQueryID { 29 return fmt.Sprintf("%06d (%s): %s: %s", se.Number, se.SQLState, se.QueryID, message) 30 } 31 return fmt.Sprintf("%06d (%s): %s", se.Number, se.SQLState, message) 32 } 33 if se.IncludeQueryID { 34 return fmt.Sprintf("%06d: %s: %s", se.Number, se.QueryID, message) 35 } 36 return fmt.Sprintf("%06d: %s", se.Number, message) 37 } 38 39 func (se *SnowflakeError) generateTelemetryExceptionData() *telemetryData { 40 data := &telemetryData{ 41 Message: map[string]string{ 42 typeKey: sqlException, 43 sourceKey: telemetrySource, 44 driverTypeKey: "Go", 45 driverVersionKey: SnowflakeGoDriverVersion, 46 stacktraceKey: maskSecrets(string(debug.Stack())), 47 }, 48 Timestamp: time.Now().UnixNano() / int64(time.Millisecond), 49 } 50 if se.QueryID != "" { 51 data.Message[queryIDKey] = se.QueryID 52 } 53 if se.SQLState != "" { 54 data.Message[sqlStateKey] = se.SQLState 55 } 56 if se.Message != "" { 57 data.Message[reasonKey] = se.Message 58 } 59 if len(se.MessageArgs) > 0 { 60 data.Message[reasonKey] = fmt.Sprintf(se.Message, se.MessageArgs...) 61 } 62 if se.Number != 0 { 63 data.Message[errorNumberKey] = strconv.Itoa(se.Number) 64 } 65 return data 66 } 67 68 func (se *SnowflakeError) sendExceptionTelemetry(sc *snowflakeConn, data *telemetryData) error { 69 if sc != nil && sc.telemetry != nil { 70 return sc.telemetry.addLog(data) 71 } 72 return nil // TODO oob telemetry 73 } 74 75 func (se *SnowflakeError) exceptionTelemetry(sc *snowflakeConn) *SnowflakeError { 76 data := se.generateTelemetryExceptionData() 77 if err := se.sendExceptionTelemetry(sc, data); err != nil { 78 logger.Debugf("failed to log to telemetry: %v", data) 79 } 80 return se 81 } 82 83 // return populated error fields replacing the default response 84 func populateErrorFields(code int, data *execResponse) *SnowflakeError { 85 err := errUnknownError() 86 if code != -1 { 87 err.Number = code 88 } 89 if data.Data.SQLState != "" { 90 err.SQLState = data.Data.SQLState 91 } 92 if data.Message != "" { 93 err.Message = data.Message 94 } 95 if data.Data.QueryID != "" { 96 err.QueryID = data.Data.QueryID 97 } 98 return err 99 } 100 101 const ( 102 /* connection */ 103 104 // ErrCodeEmptyAccountCode is an error code for the case where a DNS doesn't include account parameter 105 ErrCodeEmptyAccountCode = 260000 106 // ErrCodeEmptyUsernameCode is an error code for the case where a DNS doesn't include user parameter 107 ErrCodeEmptyUsernameCode = 260001 108 // ErrCodeEmptyPasswordCode is an error code for the case where a DNS doesn't include password parameter 109 ErrCodeEmptyPasswordCode = 260002 110 // ErrCodeFailedToParseHost is an error code for the case where a DNS includes an invalid host name 111 ErrCodeFailedToParseHost = 260003 112 // ErrCodeFailedToParsePort is an error code for the case where a DNS includes an invalid port number 113 ErrCodeFailedToParsePort = 260004 114 // ErrCodeIdpConnectionError is an error code for the case where a IDP connection failed 115 ErrCodeIdpConnectionError = 260005 116 // ErrCodeSSOURLNotMatch is an error code for the case where a SSO URL doesn't match 117 ErrCodeSSOURLNotMatch = 260006 118 // ErrCodeServiceUnavailable is an error code for the case where service is unavailable. 119 ErrCodeServiceUnavailable = 260007 120 // ErrCodeFailedToConnect is an error code for the case where a DB connection failed due to wrong account name 121 ErrCodeFailedToConnect = 260008 122 // ErrCodeRegionOverlap is an error code for the case where a region is specified despite an account region present 123 ErrCodeRegionOverlap = 260009 124 // ErrCodePrivateKeyParseError is an error code for the case where the private key is not parsed correctly 125 ErrCodePrivateKeyParseError = 260010 126 // ErrCodeFailedToParseAuthenticator is an error code for the case where a DNS includes an invalid authenticator 127 ErrCodeFailedToParseAuthenticator = 260011 128 // ErrCodeClientConfigFailed is an error code for the case where clientConfigFile is invalid or applying client configuration fails 129 ErrCodeClientConfigFailed = 260012 130 131 /* network */ 132 133 // ErrFailedToPostQuery is an error code for the case where HTTP POST failed. 134 ErrFailedToPostQuery = 261000 135 // ErrFailedToRenewSession is an error code for the case where session renewal failed. 136 ErrFailedToRenewSession = 261001 137 // ErrFailedToCancelQuery is an error code for the case where cancel query failed. 138 ErrFailedToCancelQuery = 261002 139 // ErrFailedToCloseSession is an error code for the case where close session failed. 140 ErrFailedToCloseSession = 261003 141 // ErrFailedToAuth is an error code for the case where authentication failed for unknown reason. 142 ErrFailedToAuth = 261004 143 // ErrFailedToAuthSAML is an error code for the case where authentication via SAML failed for unknown reason. 144 ErrFailedToAuthSAML = 261005 145 // ErrFailedToAuthOKTA is an error code for the case where authentication via OKTA failed for unknown reason. 146 ErrFailedToAuthOKTA = 261006 147 // ErrFailedToGetSSO is an error code for the case where authentication via OKTA failed for unknown reason. 148 ErrFailedToGetSSO = 261007 149 // ErrFailedToParseResponse is an error code for when we cannot parse an external browser response from Snowflake. 150 ErrFailedToParseResponse = 261008 151 // ErrFailedToGetExternalBrowserResponse is an error code for when there's an error reading from the open socket. 152 ErrFailedToGetExternalBrowserResponse = 261009 153 // ErrFailedToHeartbeat is an error code when a heartbeat fails. 154 ErrFailedToHeartbeat = 261010 155 156 /* rows */ 157 158 // ErrFailedToGetChunk is an error code for the case where it failed to get chunk of result set 159 ErrFailedToGetChunk = 262000 160 161 /* transaction*/ 162 163 // ErrNoReadOnlyTransaction is an error code for the case where readonly mode is specified. 164 ErrNoReadOnlyTransaction = 263000 165 // ErrNoDefaultTransactionIsolationLevel is an error code for the case where non default isolation level is specified. 166 ErrNoDefaultTransactionIsolationLevel = 263001 167 168 /* file transfer */ 169 170 // ErrInvalidStageFs is an error code denoting an invalid stage in the file system 171 ErrInvalidStageFs = 264001 172 // ErrFailedToDownloadFromStage is an error code denoting the failure to download a file from the stage 173 ErrFailedToDownloadFromStage = 264002 174 // ErrFailedToUploadToStage is an error code denoting the failure to upload a file to the stage 175 ErrFailedToUploadToStage = 264003 176 // ErrInvalidStageLocation is an error code denoting an invalid stage location 177 ErrInvalidStageLocation = 264004 178 // ErrLocalPathNotDirectory is an error code denoting a local path that is not a directory 179 ErrLocalPathNotDirectory = 264005 180 // ErrFileNotExists is an error code denoting the file to be transferred does not exist 181 ErrFileNotExists = 264006 182 // ErrCompressionNotSupported is an error code denoting the user specified compression type is not supported 183 ErrCompressionNotSupported = 264007 184 // ErrInternalNotMatchEncryptMaterial is an error code denoting the encryption material specified does not match 185 ErrInternalNotMatchEncryptMaterial = 264008 186 // ErrCommandNotRecognized is an error code denoting the PUT/GET command was not recognized 187 ErrCommandNotRecognized = 264009 188 // ErrFailedToConvertToS3Client is an error code denoting the failure of an interface to s3.Client conversion 189 ErrFailedToConvertToS3Client = 264010 190 // ErrNotImplemented is an error code denoting the file transfer feature is not implemented 191 ErrNotImplemented = 264011 192 // ErrInvalidPadding is an error code denoting the invalid padding of decryption key 193 ErrInvalidPadding = 264012 194 195 /* binding */ 196 197 // ErrBindSerialization is an error code for a failed serialization of bind variables 198 ErrBindSerialization = 265001 199 // ErrBindUpload is an error code for the uploading process of bind elements to the stage 200 ErrBindUpload = 265002 201 202 /* async */ 203 204 // ErrAsync is an error code for an unknown async error 205 ErrAsync = 266001 206 207 /* multi-statement */ 208 209 // ErrNoResultIDs is an error code for empty result IDs for multi statement queries 210 ErrNoResultIDs = 267001 211 212 /* converter */ 213 214 // ErrInvalidTimestampTz is an error code for the case where a returned TIMESTAMP_TZ internal value is invalid 215 ErrInvalidTimestampTz = 268000 216 // ErrInvalidOffsetStr is an error code for the case where a offset string is invalid. The input string must 217 // consist of sHHMI where one sign character '+'/'-' followed by zero filled hours and minutes 218 ErrInvalidOffsetStr = 268001 219 // ErrInvalidBinaryHexForm is an error code for the case where a binary data in hex form is invalid. 220 ErrInvalidBinaryHexForm = 268002 221 // ErrTooHighTimestampPrecision is an error code for the case where cannot convert Snowflake timestamp to arrow.Timestamp 222 ErrTooHighTimestampPrecision = 268003 223 224 /* OCSP */ 225 226 // ErrOCSPStatusRevoked is an error code for the case where the certificate is revoked. 227 ErrOCSPStatusRevoked = 269001 228 // ErrOCSPStatusUnknown is an error code for the case where the certificate revocation status is unknown. 229 ErrOCSPStatusUnknown = 269002 230 // ErrOCSPInvalidValidity is an error code for the case where the OCSP response validity is invalid. 231 ErrOCSPInvalidValidity = 269003 232 // ErrOCSPNoOCSPResponderURL is an error code for the case where the OCSP responder URL is not attached. 233 ErrOCSPNoOCSPResponderURL = 269004 234 235 /* query Status*/ 236 237 // ErrQueryStatus when check the status of a query, receive error or no status 238 ErrQueryStatus = 279001 239 // ErrQueryIDFormat the query ID given to fetch its result is not valid 240 ErrQueryIDFormat = 279101 241 // ErrQueryReportedError server side reports the query failed with error 242 ErrQueryReportedError = 279201 243 // ErrQueryIsRunning the query is still running 244 ErrQueryIsRunning = 279301 245 246 /* GS error code */ 247 248 // ErrSessionGone is an GS error code for the case that session is already closed 249 ErrSessionGone = 390111 250 // ErrRoleNotExist is a GS error code for the case that the role specified does not exist 251 ErrRoleNotExist = 390189 252 // ErrObjectNotExistOrAuthorized is a GS error code for the case that the server-side object specified does not exist 253 ErrObjectNotExistOrAuthorized = 390201 254 ) 255 256 const ( 257 errMsgFailedToParseHost = "failed to parse a host name. host: %v" 258 errMsgFailedToParsePort = "failed to parse a port number. port: %v" 259 errMsgFailedToParseAuthenticator = "failed to parse an authenticator: %v" 260 errMsgInvalidOffsetStr = "offset must be a string consist of sHHMI where one sign character '+'/'-' followed by zero filled hours and minutes: %v" 261 errMsgInvalidByteArray = "invalid byte array: %v" 262 errMsgIdpConnectionError = "failed to verify URLs. authenticator: %v, token URL:%v, SSO URL:%v" 263 errMsgSSOURLNotMatch = "SSO URL didn't match. expected: %v, got: %v" 264 errMsgFailedToGetChunk = "failed to get a chunk of result sets. idx: %v" 265 errMsgFailedToPostQuery = "failed to POST. HTTP: %v, URL: %v" 266 errMsgFailedToRenew = "failed to renew session. HTTP: %v, URL: %v" 267 errMsgFailedToCancelQuery = "failed to cancel query. HTTP: %v, URL: %v" 268 errMsgFailedToCloseSession = "failed to close session. HTTP: %v, URL: %v" 269 errMsgFailedToAuth = "failed to auth for unknown reason. HTTP: %v, URL: %v" 270 errMsgFailedToAuthSAML = "failed to auth via SAML for unknown reason. HTTP: %v, URL: %v" 271 errMsgFailedToAuthOKTA = "failed to auth via OKTA for unknown reason. HTTP: %v, URL: %v" 272 errMsgFailedToGetSSO = "failed to auth via OKTA for unknown reason. HTTP: %v, URL: %v" 273 errMsgFailedToParseResponse = "failed to parse a response from Snowflake. Response: %v" 274 errMsgFailedToGetExternalBrowserResponse = "failed to get an external browser response from Snowflake, err: %s" 275 errMsgNoReadOnlyTransaction = "no readonly mode is supported" 276 errMsgNoDefaultTransactionIsolationLevel = "no default isolation transaction level is supported" 277 errMsgServiceUnavailable = "service is unavailable. check your connectivity. you may need a proxy server. HTTP: %v, URL: %v" 278 errMsgFailedToConnect = "failed to connect to db. verify account name is correct. HTTP: %v, URL: %v" 279 errMsgOCSPStatusRevoked = "OCSP revoked: reason:%v, at:%v" 280 errMsgOCSPStatusUnknown = "OCSP unknown" 281 errMsgOCSPInvalidValidity = "invalid validity: producedAt: %v, thisUpdate: %v, nextUpdate: %v" 282 errMsgOCSPNoOCSPResponderURL = "no OCSP server is attached to the certificate. %v" 283 errMsgBindColumnMismatch = "column %v has a different number of binds (%v) than column 1 (%v)" 284 errMsgNotImplemented = "not implemented" 285 errMsgFeatureNotSupported = "feature is not supported: %v" 286 errMsgCommandNotRecognized = "%v command not recognized" 287 errMsgLocalPathNotDirectory = "the local path is not a directory: %v" 288 errMsgFileNotExists = "file does not exist: %v" 289 errMsgInvalidStageFs = "destination location type is not valid: %v" 290 errMsgInternalNotMatchEncryptMaterial = "number of downloading files doesn't match the encryption materials. files=%v, encmat=%v" 291 errMsgFailedToConvertToS3Client = "failed to convert interface to s3 client" 292 errMsgNoResultIDs = "no result IDs returned with the multi-statement query" 293 errMsgQueryStatus = "server ErrorCode=%s, ErrorMessage=%s" 294 errMsgInvalidPadding = "invalid padding on input" 295 errMsgClientConfigFailed = "client configuration failed: %v" 296 ) 297 298 // Returned if a DNS doesn't include account parameter. 299 func errEmptyAccount() *SnowflakeError { 300 return &SnowflakeError{ 301 Number: ErrCodeEmptyAccountCode, 302 Message: "account is empty", 303 } 304 } 305 306 // Returned if a DNS doesn't include user parameter. 307 func errEmptyUsername() *SnowflakeError { 308 return &SnowflakeError{ 309 Number: ErrCodeEmptyUsernameCode, 310 Message: "user is empty", 311 } 312 } 313 314 // Returned if a DNS doesn't include password parameter. 315 func errEmptyPassword() *SnowflakeError { 316 return &SnowflakeError{ 317 Number: ErrCodeEmptyPasswordCode, 318 Message: "password is empty", 319 } 320 } 321 322 // Returned if a DSN's implicit region from account parameter and explicit region parameter conflict. 323 func errInvalidRegion() *SnowflakeError { 324 return &SnowflakeError{ 325 Number: ErrCodeRegionOverlap, 326 Message: "two regions specified", 327 } 328 } 329 330 // Returned if a DSN includes an invalid authenticator. 331 func errFailedToParseAuthenticator() *SnowflakeError { 332 return &SnowflakeError{ 333 Number: ErrCodeFailedToParseAuthenticator, 334 Message: "failed to parse an authenticator", 335 } 336 } 337 338 // Returned if the server side returns an error without meaningful message. 339 func errUnknownError() *SnowflakeError { 340 return &SnowflakeError{ 341 Number: -1, 342 SQLState: "-1", 343 Message: "an unknown server side error occurred", 344 QueryID: "-1", 345 } 346 }