29. Jak vytvořit chybovou třídu s parametry v PHP i JavaScriptu

Ilustrační obrázek k článku: Jak vytvořit chybovou třídu s parametry v PHP i JavaScriptu
Ukážu, jak v PHP a JavaScriptu vytvořit výjimku, která nese i parametry. Tento trik vám ušetří hodiny ladění – a funguje nejen v CombiScriptu, ale i ve vašich vlastních projektech.

V minulém článku jsme slíbili, že budeme vyvolávat výjimky takto:

  1. if (...) throw new cs_Error('kod', [parametr1, parametr2, ...]);

Tento zápis funguje stejně v PHP i v Javascriptu, protože v obou jazycích se výjimky vyvolávají přes throw, nové objekty přes new a pole se zapisují pomocí hranatých závorek.

Pro tento příkaz si potřebujeme připravit příslušné třídy v obou jazycích. Uložíme je do knihovny cs_Util. Na rozdíl od knihoven jako nm_Util, st_Util nebo ar_Util nepokrývá jeden konkrétní typ, ale tvoří jádro CombiScriptu. Chybové třídy vytvoříme jako potomky (děděním) existujících tříd, abychom mohli využít vestavěnou detekci místa chyby. Tu bychom jinak museli složitě programovat sami.

V PHP je rozšiřování třídy Exception běžnou praxí – a my postupujeme klasicky. Naše dodatečná data (parametry chyby) ukládáme do privátní vlastnosti $_data. A samozřejmě - v konstruktoru nezapomeneme zavolat parent::__construct(), aby fungovalo dědění a záznam stack trace.

  1. class cs_Error extends Exception
  2. {
  3. private $_data = '';
  4. public function __construct($message, $data=[])
  5. {
  6. $this->_data = $data;
  7. parent::__construct($message);
  8. }
  9. public function getData()
  10. {
  11. return $this->_data;
  12. }
  13. }

I v JavaScriptu můžete throw vyvolat s vlastním objektem – stačí, aby dědil od Error. Podle oficiálního návodu na MDN jsme třídu cs_Error vytvořili takto:

  1. class cs_Error extends Error
  2. {
  3. constructor($message, $data=[])
  4. {
  5. super($message);
  6. if (Error.captureStackTrace) Error.captureStackTrace(this, cs_Error);
  7. this.data = $data;
  8. }
  9. getData()
  10. {
  11. return this.data;
  12. }
  13. }

Klíčové je zavolat super() a pokud je k dispozici i Error.captureStackTrace() pro zachycení zásobníku volání.

Součástí cs_Util je i funkce cs_Type(), která detekuje typ proměnné. Zatím máme jen základ - protože plná verze bude podporovat i uživatelské typy (o tom později). Prozatím tedy stačí detekce Null a Number:

  1. function cs_Type($var)
  2. {
  3. if ($var === null) return 'Null';
  4. if (nm_IsNumber($var)) return 'Number';
  5. //if (bl_IsBoolean($var)) return 'Boolean'; //TODO next
  6. //if (st_IsString($var)) return 'String';
  7. //if (ar_IsArray($var)) return 'Array';
  8. return 'Unknown';
  9. }

Ostatní typy (Boolean, String, Array) si připravíme na později – už teď ale vidíte, kam směřujeme.

Naše knihovna cs_Util tedy zatím nějak provizorně vypadá takto:

cs_Util.php.js
  1. <!-- --><?php /*
  2. "use strict";
  3. class cs_Error extends Error
  4. {
  5. constructor($message, $data=[])
  6. {
  7. super($message);
  8. if (Error.captureStackTrace) Error.captureStackTrace(this, cs_Error);
  9. this.data = $data;
  10. }
  11. getData()
  12. {
  13. return this.data;
  14. }
  15. }
  16. /*/
  17. class cs_Error extends Exception
  18. {
  19. private $_data = '';
  20. public function __construct($message, $data=[])
  21. {
  22. $this->_data = $data;
  23. parent::__construct($message);
  24. }
  25. public function getData()
  26. {
  27. return $this->_data;
  28. }
  29. }
  30. //*/
  31. function cs_Type($var)
  32. {
  33. if ($var === null) return 'Null';
  34. if (nm_IsNumber($var)) return 'Number';
  35. //if (bl_IsBoolean($var)) return 'Boolean'; //TODO next
  36. //if (st_IsString($var)) return 'String';
  37. //if (ar_IsArray($var)) return 'Array';
  38. return 'Unknown';
  39. }

Nyní už můžeme ve funkcích používat bohaté výjimky s parametry - což nám výrazně usnadní ladění a čtení chybových hlášek. V příštím článku se vrátíme ke knihovně nm_Util a probereme práci s úhly.

Předchozí   Následující