İçeriğe geç
edumintsBlog
Yazılım3 dk okuma

Hata Mantıkta Değil, Birleşim Noktasında Yaşar

Kaynak: dev.to

Paylaş
İçindekiler 5 başlık

Şifrelenmiş gizli veri (secret) bytes tipindeydi. Bellek içi (in-memory) depoda kusursuzca gidip geldi ve birim testleri (unit tests) başarıyla geçti. Ancak Postgres tarafında sütun JSON tipindeydi ve bytes JSON olarak serileştirilemezdi. Gizli veri deposu, bellek içi testin asla geçmediği o tek sınırda patladı.

HivePlane üzerindeki tüm v0.2.0 saha testinin temel örüntüsü buydu. Zor olan kısım iş mantığı (logic) değil; veri modeli ve sınırlardı. Her hata, Python içinde sorunsuz çalışan ancak bir adım sonrasında, yani bir kalıcılık (persistence) birleşim noktasında (seam) kırılan bir değerden kaynaklanıyordu. Çünkü hata, her zaman birim testinizin bir sınır ötesinde yaşar.

Her Birleşim Noktası Türü İçin Bir Hata#

Aşağıdaki sınıflandırma, hataların mantıkta değil, birleşim noktalarında nasıl ortaya çıktığını özetlemektedir:

  • D-5: Birleşim noktasını geçen değer bytes olarak şifreli metindi (ciphertext) — Postgres JSON kalıcılığı ikili (binary) veriyi reddetti.
  • D-7: id ile anahtarlanmış bir desired_specs satırı — İkinci kaynak birincil anahtar (PK) çakışmasına çarptı (id ve benzersizlik karmaşası).
  • D-8: Durdurma anahtarı (kill-switch) kaydının var olması — GET /tools/disabled uç noktası etkin araçları da listeledi (durum ve kayıt karmaşası).
  • D-9: Çalışmaları (runs) olan bir iş yükünün silinmesi — Açıklamalı bir 409 hatası yerine ham yabancı anahtar (FK) ihlali ile 500 döndü.
  • #573: alembic_head=0034 sabitleyen bir yedekleme manifestosu — Şema başlığı 0035'ti; yanlış şemaya karşı geri yükleme yapıldı.

JSON'ı Kıran Baytlar (D-5)#

Şifrelenmiş kasa, şifreli metni bytes olarak saklıyordu. Bellek içi testler geçti fakat Postgres JSON sütununda serileştirme hatası oluştu. Çözüm veri modelinde değil, sınırdaydı: Postgres'e giderken veriyi base64 ile kodlamak (encode) ve dönerken çözmek (decode). Model bytes olarak kalır, birleşim noktası ise tercüme etmeyi öğrenir.

  • Pratik Çıkarım: Bellek içi deponuz ve Postgres deponuz aynı arayüzü paylaşır ancak aynı serileştirmeyi paylaşmaz. Değerleri bellek içi testlerin geçmediği sınırlar boyunca takip edin.

İlkini Kıran İkinci Kaynak (D-7)#

Uzlaştırma yükleyicisi (reconcile loader), desired_specs tablosunu id ile anahtarlamıştı. Tek kaynak varken sorun yoktu ancak aynı durumu uygulayan ikinci bir kaynak birincil anahtar çakışmasına yol açtı. Benzersizlik kısıtlaması ile id aynı alandı fakat farklı şeyler ifade ediyorlardı.

  • Pratik Çıkarım: Çözüm, (source_id, workload_id) gibi bileşik anahtarlar (composite keys) ve idempotent upsert işlemleridir. Çoklu kaynak senaryolarını mutlaka test edin.

"Devre Dışı" Görünen Etkin Araç (D-8)#

GET /tools/disabled uç noktası, etkin araçları da içeren bir liste döndürüyordu. Tabloda durdurma anahtarı kaydı vardı ama araç aslında devre dışı değildi. Uç nokta mevcut durumu (state) değil, kaydı (record) raporluyordu.

  • Pratik Çıkarım: Sonradan geri alınmış bir işlemin kaydı güncel bir gerçek değil, tarihçedir. API'ler yalnızca ham kayıtları değil, türetilmiş gerçek durumu raporlamalıdır.

500 Döndüren Yabancı Anahtar (D-9)#

Alt çalışmaları olan bir iş yükünü silmeye çalışmak, veritabanı sınırında ham bir yabancı anahtar (FK) kısıtlama hatasına çarparak 500 dönmesine neden oldu.

  • Pratik Çıkarım: Veritabanı kısıtlama hatalarını sınırda yakalayıp kullanıcıya anlamlı bir 409 (Conflict) durumu ve açıklamasıyla sunmak, iyi API tasarımının temelidir.

Orijinal makaleye buradan ulaşabilirsiniz.

Kaynak ve atıf

Bu yazı, dev.to üzerinde yayımlanan içerikten yararlanılarak Edumints tarafından yapay zekâ desteğiyle Türkçe hazırlandı. Ayrıntılar ve yazarların kendi anlatımı için orijinaline bakabilirsin:

  • dev.to/debashish_ghosal/the-bug-lives-at-the-seam-not-in-the-logic-48j4