(t *testing.T)
| 301 | } |
| 302 | |
| 303 | func TestClassifyErrorCode(t *testing.T) { |
| 304 | tests := []struct { |
| 305 | name string |
| 306 | err error |
| 307 | expected string |
| 308 | }{ |
| 309 | {"transaction conflict", errors.New("Transaction conflict on commit"), "40001"}, |
| 310 | {"query cancelled", errors.New("context canceled"), "57014"}, |
| 311 | // Unknown error class (no DuckDB prefix) maps to XX000 — internal / |
| 312 | // infra rather than user-class — so isUserQueryError correctly |
| 313 | // routes it to the alert-worthy log path. Adding this prefix to a |
| 314 | // user class would hide real infra failures. |
| 315 | {"generic error with no DuckDB prefix", errors.New("syntax error"), "XX000"}, |
| 316 | {"SSL closed is infra not user", errors.New("SSL connection has been closed unexpectedly"), "XX000"}, |
| 317 | |
| 318 | {"catalog missing table", errors.New("Catalog Error: Table with name users does not exist!"), "42P01"}, |
| 319 | {"catalog missing table with suggestion", errors.New("Catalog Error: Table with name stg_customers__dbt_tmp does not exist!\nDid you mean \"stg_customers\"?"), "42P01"}, |
| 320 | {"catalog missing view", errors.New("Catalog Error: View with name v does not exist!"), "42P01"}, |
| 321 | {"catalog missing schema", errors.New("Catalog Error: Schema with name \"missing\" does not exist!"), "3F000"}, |
| 322 | {"catalog schema-qualified table, missing schema", errors.New("Catalog Error: Table with name \"missing_schema.t\" does not exist because schema \"missing_schema\" does not exist."), "3F000"}, |
| 323 | {"catalog missing function", errors.New("Catalog Error: Scalar Function with name no_such_func does not exist!"), "42883"}, |
| 324 | {"catalog missing type", errors.New("Catalog Error: Type with name mytype does not exist!"), "42704"}, |
| 325 | {"catalog table already exists", errors.New("Catalog Error: Table with name \"t\" already exists!"), "42P07"}, |
| 326 | {"catalog schema already exists", errors.New("Catalog Error: Schema with name \"s\" already exists!"), "42P06"}, |
| 327 | {"catalog function already exists", errors.New("Catalog Error: Function with name \"f\" already exists!"), "42723"}, |
| 328 | |
| 329 | {"binder missing column", errors.New("Binder Error: Referenced column \"missing_col\" not found in FROM clause!"), "42703"}, |
| 330 | {"binder ambiguous column", errors.New("Binder Error: Ambiguous reference to column \"id\""), "42702"}, |
| 331 | {"binder missing table alias", errors.New("Binder Error: Referenced table \"t\" not found!\nCandidate tables: \"users\""), "42P01"}, |
| 332 | {"binder function overload", errors.New("Binder Error: No function matches the given name and argument types 'foo(INTEGER)'. You might need to add explicit type casts."), "42883"}, |
| 333 | {"binder other", errors.New("Binder Error: cannot use alter table on a view because this object is not a table; use ALTER VIEW instead"), "42601"}, |
| 334 | |
| 335 | {"parser syntax", errors.New("Parser Error: syntax error at or near \"FORM\""), "42601"}, |
| 336 | {"conversion error", errors.New("Conversion Error: Could not convert string 'abc' to INT32"), "22P02"}, |
| 337 | {"conversion out of range cast", errors.New("Conversion Error: Type INT32 with value 1000 can't be cast because the value is out of range for the destination type INT8"), "22003"}, |
| 338 | {"conversion overflow", errors.New("Conversion Error: Overflow in cast from DOUBLE to INT32"), "22003"}, |
| 339 | {"out of range", errors.New("Out of Range Error: Overflow in multiplication of INT32"), "22003"}, |
| 340 | |
| 341 | {"constraint unique", errors.New("Constraint Error: Duplicate key \"id: 1\" violates primary key constraint"), "23505"}, |
| 342 | {"constraint not null", errors.New("Constraint Error: NOT NULL constraint failed: t.col"), "23502"}, |
| 343 | {"constraint foreign key", errors.New("Constraint Error: Violates foreign key constraint because key is still referenced"), "23503"}, |
| 344 | {"constraint check", errors.New("Constraint Error: CHECK constraint failed: positive"), "23514"}, |
| 345 | {"constraint generic", errors.New("Constraint Error: some other constraint failure"), "23000"}, |
| 346 | |
| 347 | {"permission denied", errors.New("Permission Error: not allowed to write here"), "42501"}, |
| 348 | {"transaction invalid", errors.New("Transaction Error: cannot begin within an existing transaction"), "25000"}, |
| 349 | {"transaction context nested begin", errors.New("TransactionContext Error: cannot start a transaction within a transaction"), "25000"}, |
| 350 | {"dependency error", errors.New("Dependency Error: Cannot drop entry because there are other entries that depend on it"), "2BP01"}, |
| 351 | {"not implemented", errors.New("Not implemented Error: MERGE INTO is not supported for this table"), "0A000"}, |
| 352 | |
| 353 | // Flight/gRPC-wrapped worker errors: the underlying DuckDB exception is |
| 354 | // embedded after "desc = " and must still classify correctly rather than |
| 355 | // leaking the raw rpc string as XX000. |
| 356 | {"flight-wrapped missing table", errors.New("flight execute update: rpc error: code = InvalidArgument desc = Catalog Error: Table with name users does not exist!"), "42P01"}, |
| 357 | {"flight-wrapped duplicate table", errors.New("flight execute update: rpc error: code = InvalidArgument desc = Catalog Error: Table with name \"t\" already exists!"), "42P07"}, |
| 358 | {"flight-wrapped missing schema", errors.New("flight execute update: rpc error: code = InvalidArgument desc = Catalog Error: Schema with name \"missing\" does not exist!"), "3F000"}, |
| 359 | {"flight-wrapped undefined column", errors.New("flight execute: rpc error: code = InvalidArgument desc = Binder Error: Referenced column \"c\" not found in FROM clause!"), "42703"}, |
| 360 | {"flight-wrapped not implemented", errors.New("flight execute update: rpc error: code = InvalidArgument desc = Not implemented Error: UPDATE on this table is not supported"), "0A000"}, |
nothing calls this directly
no test coverage detected