Tencent/WeKnora · error

create doris client: %w

Error message

create doris client: %w

What it means

This wraps an error from sql.Open("mysql", mc.FormatDSN()) when building the Doris MySQL-protocol client. sql.Open validates the DSN format and driver availability but does not connect; failures indicate a malformed DSN (bad host/port/user chars, invalid params) or the mysql driver not being registered.

Source

Thrown at internal/container/engine_factory.go:351

		return nil, fmt.Errorf("doris connection requires addr (host:port)")
	}
	if cc.Database == "" {
		return nil, fmt.Errorf("doris connection requires database")
	}

	mc := mysql.NewConfig()
	mc.User = cc.Username
	mc.Passwd = cc.Password
	utils.RegisterMySQLSSRFDialer()
	mc.Net = utils.MySQLSSRFNetwork
	mc.Addr = cc.Addr
	mc.DBName = cc.Database
	mc.Params = map[string]string{"charset": "utf8mb4"}
	mc.ParseTime = true
	mc.Loc = time.Local
	db, err := sql.Open("mysql", mc.FormatDSN())
	if err != nil {
		return nil, fmt.Errorf("create doris client: %w", err)
	}
	db.SetMaxOpenConns(20)
	db.SetMaxIdleConns(5)
	db.SetConnMaxLifetime(time.Hour)

	httpPort := cc.HTTPPort
	if httpPort <= 0 {
		httpPort = 8030
	}
	httpBase := "http://" + hostFromAddr(cc.Addr) + ":" + strconv.Itoa(httpPort)

	repo := dorisRepo.NewDorisRetrieveEngineRepository(
		db, httpBase, cc.Username, cc.Password, cc.Database, &store.IndexConfig,
	)
	return retriever.NewKVHybridRetrieveEngine(repo, types.DorisRetrieverEngineType), nil
}

// hostFromAddr 从 "host:port" 中拆出 host 部分;Addr 没有冒号时整段当作 host。

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Escape credentials with url.UserPassword or rely on mc.User/mc.Passwd (Config.FormatDSN escapes) instead of string-building the DSN
  2. Ensure Addr is pure host:port with no scheme or path
  3. Confirm the blank import _ "github.com/go-sql-driver/mysql" exists so the driver registers
  4. Note sql.Open does not connect: if you actually see connection failures at query time, check reachability of fe-host:9030 separately

Example fix

// before
db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/%s", user, rawPass, addr, dbname)) // rawPass with '@' breaks DSN
// after
mc := mysql.NewConfig()
mc.User = user
mc.Passwd = rawPass
mc.Net = "tcp"
mc.Addr = addr
mc.DBName = dbname
db, err := sql.Open("mysql", mc.FormatDSN())
Defensive patterns

Strategy: validation

Validate before calling

func validDorisDSNParts(cc types.ConnectionConfig) error {
    if _, _, err := net.SplitHostPort(cc.Addr); err != nil { return err }
    for _, r := range cc.Username + cc.Password { if strings.ContainsRune("@:/() ", r) { return fmt.Errorf("credential char %q needs escaping", r) } }
    return nil
}

Type guard

func dorisDSNReady(cc types.ConnectionConfig) bool { return validDorisDSNParts(cc) == nil }

Try / catch

db, err := sql.Open("mysql", mc.FormatDSN())
var derr *driver.ErrInvalidDSN // or check wrapped error
if err != nil {
    return fmt.Errorf("doris DSN invalid — check addr/credentials escaping and mysql driver import: %w", err)
}
if err := db.PingContext(ctx); err != nil { return fmt.Errorf("doris unreachable at %s: %w", cc.Addr, err) }

Prevention

When it happens

Trigger: createDorisEngine building a DSN from ConnectionConfig where Addr, Username, Password, or Database contain DSN-invalid characters (unescaped '@', ':', '/', '(' ')'), or the go-sql-driver/mysql driver was never imported/registered under the name "mysql".

Common situations: Passwords with special characters not escaped in the DSN; Addr containing a scheme or trailing slash; forgetful refactors dropping the driver's blank import (underscore import) after dependency cleanup.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/67bbf94fae757046. Report an issue: GitHub.