GraphQL ve Hata Sınırlarıyla Tepki'de özel hata sayfaları
Bu makaleyi beğenirseniz, lütfen ekibinize GitHub çekme istekleri için otomatik hatırlatıcılar gönderen bir Slack bot olan Çekme Hatırlatmalarını kontrol ederek beni destekleyin.
GraphQL ve React ile çalışırken son zamanlarda karşılaştığım zorluklardan biri hataların nasıl ele alınacağıydı. Geliştiriciler olarak, daha önce varsayılan olarak 500, 404 ve 403 sayfalarını sunucu tarafından oluşturulan uygulamalarda uyguladık, ancak bunun React ve GraphQL ile nasıl yapılacağını bulmak zor.
Bu yazıda ekibimizin bu soruna nasıl yaklaştığı, uyguladığımız son çözüm ve GraphQL tekniklerinden ilginç dersler hakkında konuşacağım.
Arka fon
Üzerinde çalıştığım proje React'te GraphQL, Apollo Client ve express-graphQL kullanılarak yapılan oldukça tipik bir CRUD uygulamasıydı. Kullanıcıya standart bir hata sayfası görüntüleyerek, bazı hata türlerini (örneğin, sunucu kapalıyken) ele almak istedik.
İlk zorluğumuz, hataları müşteriye iletmenin en iyi yolunu bulmaktı. GraphQL, 500, 400 ve 403 gibi HTTP durum kodlarını kullanmaz. Bunun yerine, yanıtlar yanlış giden şeylerin bir listesini içeren bir hata dizisi içerir (GraphQL spesifikasyonundaki hatalar hakkında daha fazla bilgi edinin).
Örneğin, GraphQL yanıtımızın sunucuda bir şey kırıldığında nasıl göründüğü:
GraphQL hata yanıtları HTTP durum kodu 200'ü döndürdüğünden, hatanın türünü tanımlamanın tek yolu, hata dizisini incelemektir. Hata mesajı özelliği, sunucuya atılan istisnayı içerdiğinden, bu kötü bir yaklaşım gibi görünüyordu. GraphQL spesifikasyonu, mesajın değerinin geliştiriciler için olduğunu belirtir, ancak değerin insan tarafından okunabilir bir mesaj mı yoksa programatik olarak işlenecek şekilde tasarlanmış bir şey mi olduğunu belirtmez:
Her hata, hatayı anlamak ve düzeltmek için geliştirici için bir kılavuz olarak tasarlanan hatanın bir dize açıklamasıyla birlikte anahtar iletiye sahip bir giriş içermelidir.
GraphQL Yanıtlarına Hata Kodları Ekleme
Bunu çözmek için, istemciler tarafından hataları programlı olarak tanımlamak için kullanabileceğimiz hata nesnelerimize standart hata kodları ekledik. Bu, Stripe’in REST API’sinin insan tarafından okunabilir mesajların yanı sıra string string kodları döndürmesinden esinlenmiştir.
Başlamak için üç hata koduna karar verdik: authentication_error, resource_not_found ve server_error.
Bunları GraphQL yanıtlarımıza eklemek için, kendi formatError fonksiyonumuzu, sunucuya atılan istisnaları yanıta eklenen standart kodlarla eşleştiren express-graphql'ye geçirdik. GraphQL spec genel olarak hata nesnelerine özellik eklemekten vazgeçirir, ancak bu girdileri bir uzantı nesnesine yerleştirerek izin verir.
GraphQL yanıt hatalarımız daha sonra sınıflandırılması kolaydı:
Apollo-server'ın express-graphql tarafından oluşturulan cevaplara kod ekleme yolumuzu geliştirmemize rağmen, benzer yerleşik davranışlar öneriyor.
Hata Sayfalarını Tepki Hatası Sınırlarıyla birlikte oluşturma
Sunucumuzdaki hataları ele almanın iyi bir yolunu bulduğumuzda, dikkatimizi müşteriye yönelttik.
Varsayılan olarak, bir server_error, authorization_error veya authorization_not_found ile karşılaştığımızda uygulamamızın global bir hata sayfası (örneğin, “bir şeyler ters gitti” mesajını içeren bir sayfa) göstermesini istedik. Ancak, istersek, esnekliğin belirli bir bileşendeki bir hatayı idare edebilmeyi de istedik.
Örneğin, bir kullanıcı bir arama çubuğuna bir şeyler yazıyorsa ve bir şeyler ters giderse, hata sayfasına yanıp sönmek yerine bağlam içinde bir hata mesajı görüntülemek istedik.
Bunu başarmak için ilk olarak, apollo-müşterisinin Query ve Mutation bileşenleri ile ortaya konacak çocukları arasında oturacak GraphqlErrorHandler adlı bir bileşen yarattık. Yanıttaki hata kodları için kontrol edilen bu bileşen, önem verdiğimiz bir kodu tanımladıysa bir istisna attı:
GraphqlErrorHandler'ı kullanmak için apollo-istemcinin Sorgu ve Mutasyon bileşenlerini tamamladık:
Ardından özellik bileşenimiz, react-apollo'ya doğrudan erişmek yerine kendi Query bileşenimizi kullandı:
Artık React uygulamamızın sunucu hatalar döndürdüğünde istisnalar attığı için, bu istisnaları ele almak ve uygun davranışla eşleştirmek istedik.
Önceden, amacımızın global hata sayfalarını (örneğin, “bir şeyler ters gitti” mesajını içeren bir sayfa) görüntülemek için varsayılan olduğunu, ancak istenirse herhangi bir bileşende yerel olarak bir hatayı işleme esnekliğine sahip olduğunu unutmayın.
Tepki hatası sınırları, bunu yapmanın harika bir yolunu sağlar. Hata sınırları şunlardır: Alt bileşen ağaçlarının herhangi bir yerinde JavaScript hatalarını yakalayabilen React bileşenleridir, böylece bunları özel davranışlarla halledebilirsiniz.
Sunucu ile ilgili herhangi bir istisnaları yakalayan ve uygun hata sayfasını görüntüleyen GraphqlErrorBoundary adlı bir hata sınırı oluşturduk:
Hata sınırını, uygulamamızın tüm bileşenleri için sarmalayıcı olarak kullanıyoruz:
Bir bileşendeki hataları, hata sayfası oluşturmak yerine işlemek istiyorsak, bileşen ağacında daha derin bir sınır kullanılabilir.
Örneğin, bileşenimizde özel hata işleme davranışını daha önce kullanmak istiyorsak, göründüğü gibi:
Sarmak
GraphQL hala nispeten yenidir ve hata işleme, geliştiricilerin karşılaştıkları gibi görünen yaygın bir sorundur. GraphQL yanıtlarımızda standart hata kodları kullanarak, hataları müşterilere kullanışlı ve sezgisel bir şekilde iletebiliriz. React uygulamalarımızda, hata sınırları, uygulamamızın hata işleme davranışını standartlaştırmak için mükemmel bir yol sağlarken ihtiyaç duyduğumuzda esnekliğe sahiptir.