NodeRed – Hataları Yakalamak

Projenizde kullandığınız node sayısı ve akışlar aracılığıyla kurulan etkileşimler arttıkça hata çıkma olasılıkları da artar. Bu nedenle hataları yakalayacak yöntemleri bilmeli ve kullanmayı alışkanlık haline getirmelisiniz.

Her programlama dilinde olduğu gibi, Node-RED de akışlardaki hataların tespit edilebilmesi/yakalanabilmesi için çeşitli yollar vardır. Bunlardan ilki ve en çok kullanılanı debug paneldir. Diğeri ise konsol günlüğüdür. Bu günlüğün görüntülenebilmesi için Node-RED ile birlikte gelen node-red-log aracı kullanılır. Bu  şekilde günlüğe yazılan hatalar sadece onları görmek açısından faydalıdır. Akışın çalışması sırasında onları kontrol ederek farklı bir aksiyon alabilmeniz için bir fayda sağlamaz.

Diğer bir tür hata yakalama mekanizması da catch adlı node’dur. Bu node çalışma sırasında hataların tespit edilmesi ve akışın farklı kollara yönlendirilmesi için kullanılabilir. İlerleyen başlıklarda tüm bu hata kontrol özellikleri detaylı olarak incelenmiştir.

Hataları izlemek

Bir node kendinde oluşacak hataları genellikle debug panel’e yazdırır. Hataların debug panele yazdırılması tercihi node’un programcısına aittir ve node’un tahmin edilebilir hataları dikkate alacak şekilde kodlanmış olmasını gerektirir. Aşağıda bir Telegram eklentisinin debug panele yazdırdığı hata mesajı gözüküyor.

Debug panele yazdırılan bir hata mesajı

Debug panele yazdırılan hata mesajı, hatanın neden kaynaklandığı ile ilgili bir açıklama ve hatanın oluşma zamanını içerir. Debug panelde listelenen her mesajın sağ üst kısmında mesajı gönderen node’un id’si (8425077f.53ac38) yer alır. Bu id’nin üzerine fare ile tıklatırsanız ilgili node’un çalışma alanı üzerinde ışıklandırılmasını sağlayabilirsiniz. Node, etkin çalışma alanında değilse, node’un yer aldığı akış çalışma alanına otomatik olarak geçiş yapılır. Aşağıdaki görselde bu şekilde ışıklandırılan node’un etrafındaki kırmızı renkli ve kesikli çizgiler gözüküyor. Özellikle büyük akışlarda bu özellik çok yardımcıdır.


Hatayı üreten node’un ışıklandırılması

Konsol günlüğü

Hata mesajları aynı zamanda Node-RED’in konsol günlüğüne de yazılır. settings.js aracılığı ile detay seviyesi yapılandırılabilen mesajlar, node-red-log aracıyla görüntülenebilir. node-red-log aracını konsolda çalıştırdığınızda aşağıdaki gibi bir çıktı verir ve beklemeye başlar. Bekleme sırasında akışlardan gelen hata ve bilgi mesajları konsolda gösterilmeye devam edilir. Aracı sonlandırıp görüntülemeyi bitirmek için Ctrl+C tuş bileşimi kullanılabilir.

Konsol günlüğünde başlatılan ve durdurulan akışlar ile node’ların bildirdiği mesajlar görüntülenir. Bildirilen mesajların konsol günlüğü tarafından hangi detayda yakalanacağı ile ilgili çeşitli ayarlar vardır. Bu ayarlar ~/.node-red/settings.js dosyasında yer alan logging özelliği ile kontrol edilir. logging özelliğine ait yapılandırma seçenekleri aşağıdaki settings.js dosyasının içeriğinde gözükmektedir.

Yukarıdaki örnek yapılandırmada gözüktüğü üzere, logging yani günlük kaydı console’a yapılmakta ve detay seviyesi olarak da detaylı bir kayıt türü olan debug seçilmiştir. level özelliğinde kullanılabilecek diğer detay seviyeleri ve anlamları şöyledir:

  • fatal: Uygulamayı kullanılmaz duruma getiren durumlara ait mesajları.
  • error: Uygulamada oluşan önemli hatalara ait mesajlar.
  • warn: Önemli olmayan fatal ve error haricindeki mesajlar.
  • info: Uygulamanın çalışması sırasındaki genel bilgi mesajları.
  • debug: fatal, error, warn ve info detay seviyesindeki tüm mesajlar.
  • trace: Son derece detaylı mesajlar.
  • off: Tüm detay seviyelerini etkisizleştirir.

logging console özelliği içinde kullanılabilecek diğer seçenekler ve anlamları ise şunlardır:

  • metrics: Bu özelliğe true değeri verildiğinde Node-RED’in çalışması sırasın işletilen akışlar ve bellek kullanımları da konsol günlüğünde listelenir. Bellek kullanım bilgisi her 15 sn. de bir güncellenir.
  • audit: Bu özellik true yapıldığında, Admin API’a yapılan erişim istekleri de konsol günlüğünde gösterilir.

Aşağıdaki örnek konsol günlüğü çıktısında metrics ve audit özellikleri etkinleştirilmiştir.

settings.js dosyasında yapılan değişikliklerin etkin olması için nodered servisinin aşağıdaki gibi yeniden başlatılması gerekir. Yukarıdaki örnek çıktıda sırasıyla admin kullanıcısının /flows dizinine yeni bir akış Deploy ettiği ve ardından da akışın disk dosyasına yeni bir revizyon numarası ile kaydedildiği anlaşılıyor. Ardından gelen event satırında ise akışta kullanılan bir debug node’a mesaj ulaştığı anlaşılıyor. Son iki satırda ise sırasıyla Node-RED’in çalışması için ayrılan ve o anda kullanılan bellek miktarları byte cinsinden listelenmiştir.

Yakalanabilir hatalar

Hataları tespit etmeyle ilgili diğer yöntem ise akışın çalışması sırasında oluşacak hata bildirimlerini dinleyerek hatanın türüne göre akışı farklı bir yöne çevirmektir. Bunu yapmak için catch node (hata yakalama düğümü) adındaki node’dan faydalanılır. catch node kuralına uygun şekilde hata bildirimi yapan node veya kodların hata bildirimlerini yakalayarak yeni bir akış belirleyebilmenizi sağlar.

Catch node

Node paletinin common grubunda yer alan catch node, aynı akış tabı içinde yürürlükte olan tüm node’ların hata bildirimlerini dinleyebilir. Ancak catch node tarafından yakalanan hata mesajları debug panelde görüntülenmez. Aşağıda catch node’un özellikler paneli görünüyor.

catch node’un özellikler paneli

catch node tarafından yakalanan hata msg nesnesinin error özelliği (msg.error) ile çıkışa aktarılır. Tahmin edebileceğiniz gibi; error özelliğinin de dâhil edildiği yeni mesajın çıkışa aktarılması yeni bir akışı başlatabilme imkânı doğurur. Aşağıdaki akış şemasını inceleyelim.


Catch node’un temel kullanım örneği ve msg.error özelliği

Yukarıdaki şemada birbirinden bağımsız iki akış yer almaktadır. Birinci akışta, kullanıcının akışı elle başlatabilmesi için bir inject node kullanılmış ve çıkışı sahte bir hata üreten function node’una bağlanmıştır. Kullanıcı inject node’un solundaki kutuya fare ile tıklattığı anda o akış sayfası içinde geçerli olan bir hata mesajı yayınlanacaktır. İkinci akışta ise o akış sayfasına ait hata bildirimlerini dinleyen bir catch (yakala) node’u yer alır ve çıktısı debug node (msg.error özelliğini göstermek üzere ayarlanmıştır) aracılığıyla debug panele yansıtılır. inject node’a tıklatıldığında oluşan hatanın dökümü yukarıdaki görselde msg.error nesnesi içinde yer almaktadır. msg.error nesnesini incelediğinizde içerisinde message, source, id vb. çeşitli özellikler yer aldığını görebilirsiniz. catch node tarafından üretilen ve msg nesnesine eklenen error özelliğinin tam içeriği aşağıdaki gibidir.

Bu JSON ağacında yer alan source özelliği hatanın kaynağına dair bilgileri tutar. Hatanın bir function mı yoksa node tarafından mı üretildiği. Hatanın üretildiği function ya da node’un adı ve kaç kez üretildiği gibi bilgiler yer alır. messages özelliği ise üretilen hata mesajının içeriğini sağlar.

catch node yukarıdaki error nesnesini kullanarak yakaladığı hata bildirimlerini çıkışına aktarır. Bu node’un daha işlevsel kullanımlarında çıkışına bir function node yerleştirilerek hatanın türüne göre akış farklı bir dala yönlendirilebilir. Yukarıdaki örnek akışı içeri aktarmak için (import) GitHub kaynağını[1] kullanabilirsiniz veya akışı elle oluşturmak için aşağıdaki özellikler panellerine ait görüntülerden faydalanabilirsiniz.

Akışı oluşturan node’ların özellikler panelleri

Akışta yer alan function node, node.js’nin hata log’lama (günlük tutma) işlevinin bir arabirimi olan node.error metodunu kullanmaktadır. Bu NodeJS kodu çalıştığında mevcut mesaj (msg) nesnesine atıfta bulunularak Node-RED içinde bir hata mesajı yayınlanır. Yayınlanan hata mesajının kaynağı node.error’a ikinci parametre olarak geçilen msg nesnesidir.

catch node aynı akış tab’ı içinde bulunan tüm node’ları dinleyebilir. Aynı zamanda sadece belli bir node tarafından üretilen hataları dinlemek üzere de yapılandırılabilir. Bunun için Catch errors from liste kutusundan uygun seçimi yapabilirsiniz. Ayrıca Ignore errors handled by other Catch nodes seçimi ile akış sayfasındaki diğer catch node’lar devre dışı bırakılabilir.

Daha önce catch node’un yeni bir akış doğurabilme imkânından bahsetmiştik. Dilerseniz şimdi buna bir örnek verelim. Daha önce birden fazla çıkışa sahip function node’ların kullanımına yer vermiştik. Aşağıdaki akışta node’lardan birinin ürettiği hata bildirimi, catch node’u ile yakalanmakta ve function node’u ile hatanın türüne göre farklı iki akış kolluna yönlendirilmektedir. Akışın JSON kaynağını indirmek için sayfa sonundaki bağlantıyı ziyaret edebilirsiniz[2].

catch node ile akışın yönlendirilmesi

Yukarıdaki akışın çalışma şekli şöyledir; 1 numaralı koldaki inject node tıklandığında akış mesajı “Rastgele hata üret” adlı function node’a geçer. node.error işlevi ile hata bildirimi yayınlanmasını sağlayan function node’a ait JavaScript kodu şu şekildedir:

Hata mesajı yayınlayan JavaScript kodu

Bu JavaScript kodu hata bildirim mesajı (messages) olarak rastgele üretilen bir sayıyı yayınlamaktadır. Bu sayı 0 ile 1 arasında float (ondalıklı) türünde bir sayıdır. İki numaralı koldaki catch node’u da hata bildirimlerini dinlemekte ve yakaladığı hatayı aşağıdaki biçimde çıkışına aktarmaktadır.

Yukarıdaki JSON biçimli hata mesajından üretilen rastgele sayının 0.12905182066837417 olduğu gözükmektedir. Ayrıca hatayı üren fonksiyonun adı olan “Rastgele hata üret” değeri de name özelliğinde yer almaktadır. Bu mesaj sıradaki “Karşılaştır” isimli function node’una gönderilir. Function node’unun karşılaştırmayı yapan JavaScript kodu aşağıda gözükmektedir. Bu kod ile akış, üretilen rastgele sayı 0.5’den ufaksa “Akış 1” isimli kola, değilse “Akış 2” isimli kola yönlendirilmektedir. Bu kollar birer debug node’dan oluşmuştur ve her biri de msg.payload değerini debug paneline yansıtmaktadır.

Akışı şarta bağlı olarak kollara yönlendiren JavaScript kodu

Yukarıdaki kodun çalışmasından satır satır bahsetmek gerekirse;

  1. catch node tarafından gönderilen msg.error.message özelliğinin değeri yazımı kısaltmak için msg_val (mesajın değeri) adlı değişkene aktarılmıştır.
  2. msg_val değeri string bir değer olduğundan sayısal karşılaştırma yapılabilmesi için parseFloat ile sayısal bir değere çevrilmiştir. if şartında (eğer) ise sayısal değerin de 0.5’den küçük olması durumu kontrol edilmiştir.
  3. Eğer şart gerçekleşmişse msg.payload (ki bu debug node’un debug panele yansıtacağı değerdir) içeriği msg.error.message ile gönderilen sayısal değer ile “, 0.5 den KUCUK.” string ifadesinin birleşiminden oluşturulmuştur.
  4. Birinci akışa karşılık gelen geri dönüş değeri null verildiği için bu akış koluna mesaj ulaştırılmaz. msg adlı mesaj nesnesi, function node’un ikinci çıkışına ulaştırılır. Bu durumda “Akış 2” isimli debug node msg.payload mesajını debug panelde görüntüler.
  5. if şartının sağlanmadığı durumda bu satır çalışır ve msg.payload içeriğinin msg.error.message ile gönderilen sayısal değer ile “, 0.5 den BUYUK.” string ifadesinin birleşiminden oluşmasını sağlar.
  6. Bu satırda 5. satırın tersi olacak şekilde mesaj “Akış 1” isimli debug node’a yönlendirilmiştir. Bu durumda rastgele üretilen sayı 0.5’den büyük ise bu akış “Akış 1” isimli node’un yer aldığı koldan devam eder.

Yakalanamayan hatalar

Debug panele veya günlüğe yazılan mesajların hepsi catch node ile yakalanabilen türde mesajlar olmayabilir. Bunun nedeni genel olarak ilgili kodun oluşturduğu hata mesajını çalışma zamanı (runtime) sırasında bildirecek özelliklerden yoksun olmasıdır. Bazı node’lar hata bildirimi için status node ile gözlenebilecek durum özelliğini kullanabilirler. Hataların düzgün bildirildiğinden veya status node’un bu amaçla kullanılıp kullanılamayacağından şüpheniz varsa node’un yazarı ile iletişim kurabilirsiniz veya ilgili node’un dokümantasyonuna göz atabilirsiniz.

Yakalanamayan istisnalar

Bazen Node-RED’in çalışması sırasında bazı öngörülemeyen dolayısıyla istisna kontrolleri yapılmamış hatalar da oluşabilir. Her yeni sürümde düzeltilen bu hatalar gerçekleştiğinde Node-RED çalışmayı durdurur ve kapanır. Çünkü yapılacak en güvenli şey budur. node.js dokümanlarında bu durum şöyle açıklanmıştır:

“Yakalanmayan bir istisnadan sonra normal olarak devam etmeyi denemek, bilgisayarı yükseltirken güç kablosunu çıkarmaya benzer. On kereden dokuzunda hiçbir şey olmaz; ancak onuncu kez sistem bozulur.”

Bu hataların tipik bir nedeni, bir node’un eş zamansız (asenkron) bir görevi başlatması ve o görevin de kontrol edilmeyen bir hata ile karşılaşmasıdır. Normalde programcısı tarafından iyi kodlamış bir node, o hatayı algılayacak kontrol kodlarını da içermelidir. Ancak kontrol kodları yoksa hata da algılanamaz.

Bu tür bir hatayla karşılaştığınızı düşündüğünüzde, hataya hangi düğümün neden olabileceğini belirmeye çalışarak node’un programcısını bilgilendirebilir ve bu konuda bir hata raporu oluşturup göndermeye çalışabilirsiniz. Ancak eş zamansız ya da asenkron (multi thread) çalışan bu kod bloklarında hatanın konumunu tespit etmek her zaman kolay bir iş değildir. Node-RED’in konsol günlüğü mesaj detay seviyelerinden biri olan trace değeri hatayı teşhis etmenizde size faydalı olabilir.


[1] catch node örneği – github.com/enseitankado/raspberry-pi/blob/master/node-red/example-catch-node.json

[2] catch node ile akışı kollara ayırmak – https://github.com/enseitankado/raspberry-pi/blob/master/node-red/example-catch-two-branch.json

Yazar: Özgür Koca

Yazar - Tankado.com

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

Bu site, istenmeyenleri azaltmak için Akismet kullanıyor. Yorum verilerinizin nasıl işlendiği hakkında daha fazla bilgi edinin.