распознавание: большие раздачи размечаются целиком, файлы вне плана видны
- модель адресует файл номером строки нашего списка вместо копии пути: ответ на 180 файлов вместо ~15k токенов стоит ~2.5k, усечение сотней снято, max_files и max_tokens ушли в [recognition], correction-ретрай больше не переприсылает список - негодный элемент ответа отбрасывается поимённой причиной, обрыв генерации и отказ по размеру запроса названы своими причинами, покрытие плана блокирует авто только при непокрытом видеофайле - раскладка показывает все файлы раздачи со строками «не в плане» и полным порядком сортировки; снимок списка файлов лёг рядом с планом (миграция 0012)
This commit is contained in:
@@ -96,16 +96,36 @@ func TestМиграцииБезAutoincrementИСерверногоВремени
|
||||
// docs/conventions/errors.md: сравнение ошибок — errors.Is/errors.As, никогда
|
||||
// по тексту. errorlint ловит `err == ErrX` и приведение типа, но не матчинг
|
||||
// подстрокой — его ловим здесь.
|
||||
//
|
||||
// Прямой формы мало: `msg := strings.ToLower(err.Error())` и следом
|
||||
// `strings.Contains(msg, …)` — то же сравнение по тексту, просто через
|
||||
// промежуточную переменную (так оно и просочилось в recognize). Поэтому вторым
|
||||
// проходом собираем имена, которым присвоен `.Error()`, и ищем их в тех же
|
||||
// сравнениях.
|
||||
func TestОшибкиНеМатчатсяПоТексту(t *testing.T) {
|
||||
re := regexp.MustCompile(`(strings\.(Contains|HasPrefix|HasSuffix|EqualFold)\([^)]*\.Error\(\)|\.Error\(\)\s*==)`)
|
||||
direct := regexp.MustCompile(`(strings\.(Contains|HasPrefix|HasSuffix|EqualFold)\([^)]*\.Error\(\)|\.Error\(\)\s*==)`)
|
||||
// Присваивание текста ошибки переменной, в т.ч. завёрнутое в вызовы
|
||||
// (strings.ToLower, strings.TrimSpace и подобные).
|
||||
assigned := regexp.MustCompile(`(?m)^\s*(\w+)\s*:?=\s*(?:[\w.]+\()*\s*[\w.]+\.Error\(\)`)
|
||||
const why = "ошибку матчим через errors.Is/errors.As, а не по тексту сообщения"
|
||||
for _, path := range goFiles(t) {
|
||||
body, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("читаю %s: %v", path, err)
|
||||
}
|
||||
if loc := re.FindIndex(body); loc != nil {
|
||||
rel, _ := filepath.Rel(repoRoot, path)
|
||||
t.Errorf("%s:%d — ошибку матчим через errors.Is/errors.As, а не по тексту сообщения", rel, lineOf(body, loc[0]))
|
||||
rel, _ := filepath.Rel(repoRoot, path)
|
||||
if loc := direct.FindIndex(body); loc != nil {
|
||||
t.Errorf("%s:%d — %s", rel, lineOf(body, loc[0]), why)
|
||||
}
|
||||
for _, m := range assigned.FindAllSubmatch(body, -1) {
|
||||
name := regexp.QuoteMeta(string(m[1]))
|
||||
used := regexp.MustCompile(
|
||||
`strings\.(Contains|HasPrefix|HasSuffix|EqualFold)\(\s*` + name + `\b` +
|
||||
`|\b` + name + `\s*==\s*"` + `|"\s*==\s*` + name + `\b`)
|
||||
if loc := used.FindIndex(body); loc != nil {
|
||||
t.Errorf("%s:%d — %s (текст ошибки положен в %s)",
|
||||
rel, lineOf(body, loc[0]), why, m[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user