{"record":{"id":"c3ead8a9e895db7f","repo":"risingwavelabs/risingwave","slug":"sinkerror-sqlserver-anyhow-err","errorCode":null,"errorMessage":"SinkError::SqlServer(anyhow!(err))","messagePattern":"SinkError::SqlServer\\(anyhow!\\(err\\)\\)","errorType":"exception","errorClass":"SinkError::SqlServer","httpStatus":null,"severity":"error","filePath":"src/connector/src/sink/mod.rs","lineNumber":1291,"sourceCode":"        SinkError::File(error.to_report_string())\n    }\n}\n\nimpl From<RpcError> for SinkError {\n    fn from(value: RpcError) -> Self {\n        SinkError::Remote(anyhow!(value))\n    }\n}\n\nimpl From<RedisError> for SinkError {\n    fn from(value: RedisError) -> Self {\n        SinkError::Redis(value.to_report_string())\n    }\n}\n\nimpl From<tiberius::error::Error> for SinkError {\n    fn from(err: tiberius::error::Error) -> Self {\n        SinkError::SqlServer(anyhow!(err))\n    }\n}\n\nimpl From<::elasticsearch::Error> for SinkError {\n    fn from(err: ::elasticsearch::Error) -> Self {\n        SinkError::ElasticSearchOpenSearch(anyhow!(err))\n    }\n}\n\nimpl From<::opensearch::Error> for SinkError {\n    fn from(err: ::opensearch::Error) -> Self {\n        SinkError::ElasticSearchOpenSearch(anyhow!(err))\n    }\n}\n\nimpl From<tokio_postgres::Error> for SinkError {\n    fn from(err: tokio_postgres::Error) -> Self {\n        SinkError::Postgres(anyhow!(err))","sourceCodeStart":1273,"sourceCodeEnd":1309,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/connector/src/sink/mod.rs#L1273-L1309","documentation":"This is RisingWave's SinkError wrapping a tiberius (SQL Server client) error. Any error surfaced by the tiberius driver during interaction with a SQL Server sink target is converted via the From impl into the SqlServer variant, losing the typed error but preserving the message via anyhow.","triggerScenarios":"Any tiberius::error::Error propagated while writing to or connecting to a SQL Server sink: failed TCP/TLS handshake, login failure, query execution failure, or protocol errors during bulk insert.","commonSituations":"Wrong SQL Server host/port in the connection string, invalid credentials, SQL Server TLS requiring encryption the client cannot negotiate, firewall blocking port 1433, or SQL Server syntax/data-type issues during sink writes.","solutions":["Verify the SQL Server endpoint is reachable (host, port 1433, firewall rules) with sqlcmd or telnet.","Check credentials and authentication mode (SQL auth vs Windows auth) in the sink connection string.","Enable/align TLS settings: match Encrypt/trust-server-certificate options between client and server.","Inspect the inner tiberius message with RUST_BACKTRACE=1 or structured logging to identify the exact driver failure.","Confirm the target database and table exist and the user has INSERT permissions."],"exampleFix":"// before: opaque wrapped error\nSinkError::SqlServer(anyhow!(err))\n// after: log the underlying tiberius error kind for diagnosis\nmatch &err {\n    tiberius::error::Error::Io(io) => tracing::error!(\"sql server io error: {io}\"),\n    tiberius::error::Error::Server(server) => tracing::error!(\"sql server rejected: {server}\"),\n    _ => {}\n}\nSinkError::SqlServer(anyhow!(err))","handlingStrategy":"retry","validationCode":"// before creating the sink: probe SQL Server reachability\nuse tiberius::{Config, AuthMethod};\nlet mut cfg = Config::new();\ncfg.host(host).port(port).authentication(AuthMethod::sql_server(user, pass));\nmatch tiberius::Client::connect(cfg, tokio::net::TcpStream::connect((host, port)).await?).await {\n    Ok(_) => println!(\"sql server reachable\"),\n    Err(e) => eprintln!(\"pre-check failed: {e}\"),\n}","typeGuard":null,"tryCatchPattern":"// match on the tiberius error kind for retry vs fatal decision\nmatch err.downcast_ref::<tiberius::error::Error>() {\n    Some(tiberius::error::Error::Io(_)) => retry_with_backoff(),\n    Some(tiberius::error::Error::Server(_)) => fatal(),\n    _ => fatal(),\n}","preventionTips":["Pre-flight the connection string with sqlcmd before creating the sink.","Keep SQL Server TLS/encryption settings consistent with the driver's.","Monitor network/firewall changes on port 1433.","Grant the sink login explicit INSERT rights on the target table."],"tags":["rust","sql-server","sink","network"],"backgroundTag":"api-request-failed","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}