Ako nájsť chybu v apke pomocou polenia intervalu
Ak programujete, tak sa s polením intervalu (bisekciou) pravdepodobne stretávate často a ani si to moc neuvedomujete. Väčšinou to bude pri hľadaní chýb.
Po aktualizácii jednej knižnice v našej UI apke sme sa dostali do vcelku nepríjemnej situácie. Prestala fungovať jedna z jej častí. Spravili sme revert a začali hľadať chybu.
Sú v podstate dva spôsoby ako takúto chybu odhaliť. Buď pomocou Gitu alebo manuálne. Oba sú však postavené na rovnakom základe.
Nájdenie zlej revízie pomocou Gitu
Pri práci s Gitom je možné použiť príkaz git bisect
. Ten slúži na
identifikovanie zmeny, ktorá spôsobila, že vaša apka sa prestala chovať podľa
očakávania.
Spočíva to v tom, že označíte revíziu ktorá je pokazená a následne revíziu, ktorá ešte fungovala. Následne Git pre vás vyberie revíziu medzi nimi a tú opäť označíte za pokazenú alebo funkčnú. A takto sa viac a viac zmenšuje interval medzi funčknou a nefunkčnou revíziou, až nakoniec nájdete revíziu, ktorá apku rozbila.
V praxi to môže potom vypadať takto:
$ git bisect start
$ git bisect bad HEAD
$ git bisect good 153d377
Bisecting: 3 revisions left to test after this (roughly 2 steps)
[3366a36571a115ee579fa8fac9818352d34fd4cf] Merge pull request #43 from ujovlado/prev-next-tuning
$ git bisect bad
Bisecting: 1 revision left to test after this (roughly 1 step)
[ea42b2839c2178cc3d771342b8b33afff21cbfca] Merge pull request #42 from ujovlado/prev-next-init
$ git bisect good
Bisecting: 0 revisions left to test after this (roughly 0 steps)
[ef5fa78913880e69850f93778494ba4a95ed0703] Keep previous/next size even if displayed alone
$ git bisect bad
ef5fa78913880e69850f93778494ba4a95ed0703 is the first bad commit
commit ef5fa78913880e69850f93778494ba4a95ed0703
Author: Vladimír Kriška <ujovlado@users.noreply.github.com>
Date: Sat Jan 9 22:52:40 2021 +0100
Keep previous/next size even if displayed alone
components/PreviousAndNextPost.js | 44 +++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 11 deletions(-)
$ git bisect reset
Tento spôsob sme ale v našom prípade použiť nemohli, pretože sa jednalo o zmenu v rámci jednej revízie. Že je zlá vieme hneď, bez hľadania.
Manuálne nájdenie chyby
Pri manuálnom hľadaní chyby väčšinou potrebujete zistiť, ktorá časť súboru je pokazená, prípadne ktorú časť súboru alebo vstupu vaša apka nevie spracovať.
TypeError: Super expression must either be null or a function.
Na základe správy vyššie sme po chvíli zistili, že chyba je v tom ako sa pripravuje balíček apky (tzv. build).
Aktualizácia devDependencies
(Webpack a pod.) nepomohla, veľa závislostí má
totiž zafixovanú verziu v yarn.lock
súbore. Tak sme ho pokusne zmazali.
Pomohlo.
Oprava je teda možná aktualizáciou všetkých závislostí. Čo nie je
úplne najšťastnejšie, a to napriek tomu, že jednotlivé knižnice sú nastavené
tak, že aktualizácia by bola v rámci major verzie (napr. ^16.8.0
).
Potrebovali sme identifikovať, ktorú knižnicu treba aktualizovať, aby sa problém vyriešil. A tak sme využili polenie intervalu. Je to taký "manuálny bisect". 🙂
Začal som mazať časti yarn.lock
súboru. Zmazal som jeho prvú polovicu a
spustil príkaz yarn
. Apka nenabehla, takže som vedel, že chyba je spôsobená
nejakou starou knižnicou v druhej polovici súboru.
Presunul som sa na druhú polovicu yarn.lock
súboru. Zmazal som z nej prvú
polovicu a spustil príkaz yarn
. Apka nenabehla, takže som vedel, že ...
A pokračoval som rovnakým spôsobom ďalej, kým sa okruh podozrivých knižníc zúžil na minimum.
Podľa jednotlivých knižníc som identifikoval, že problém bude spôsobený pravdepodobne knižnicou Terser. A tak to aj bolo. Táto knižnica je zodpovedná za minifikáciu kódu, používa ju Webpack.
Následne som zmazal terser
a terser-webpack-plugin
z yarn.lock
súboru,
spustil príkaz yarn
, ktorý tieto dve knižnice aktualizoval a bolo po probléme.
Nakoniec to nebolo až také zložité, ako sa na začiatku zdalo, pretože veľkosť súboru sa zmenší vždy o polovicu, a tak stačí pár krokov a chyba je odhalená.