---
title: 'Hata ve Uyarı Durumları'
source: 'https://academia.sh/tr/kurslar/arayuz-temelleri/hata-ve-uyari-durumlari'
course: 'Arayüz Tasarımının Temelleri'
language: tr
updated: '2026-08-17T18:09:35+00:00'
license: 'CC BY-SA 4.0'
---

# Hata ve Uyarı Durumları

Hatanın kaynağa ve kurtarılabilirliğe göre sınıflandırılması, doğrulama anının ürettiği ileti sayısının hesabı, önlenebilir hataların ayıklanması ve iletinin yakınlık kuralıyla yerleştirilmesi.

Önceki ders boşluğun bir hata olmadığını gösterdi: sistem doğru çalışmış, sonuç
gelmemişti. Sistemin doğru çalışmadığı ya da kullanıcının verdiği girdinin kabul
edilemediği durumlar ise ayrı bir tasarım gerektirir.

Katalog arayüzünde üç ayrı örnek var: ISBN alanına geçersiz bir değer girildi, ödünç alma
isteği sunucuya ulaşamadı, kullanıcının ödünç alma hakkı doldu. Üçü de "hata" diye
adlandırılır ama üçünün kurtarma yolu farklıdır. Birincisinde kullanıcı girdiyi düzeltir,
ikincisinde tekrar dener, üçüncüsünde yapabileceği bir şey yoktur. Aynı kutuda sunulamazlar.

## Hata Kaynağa ve Kurtarılabilirliğe Göre Ayrılır

Sınıflandırma iki soruya dayanır: hata nereden geldi ve kullanıcı bunu düzeltebilir mi?

- **Girdi hatası, kurtarılabilir.** Kullanıcının verdiği değer kabul edilmedi. Kurtarma yolu
  değeri düzeltmektir. İleti alanın yanında durur ve neyin beklendiğini söyler.
- **Durum hatası, kurtarılabilir.** İşlem yapılamaz çünkü sistemin durumu uygun değil —
  kayıt başkasında, hak dolmuş. Kurtarma yolu farklı bir eylemdir: rezervasyon, iade
  tarihini bekleme. İleti eylemin yanında durur ve alternatifi gösterir.
- **Geçici sistem hatası, kurtarılabilir.** İstek ulaşmadı ya da zaman aşımına uğradı.
  Kurtarma yolu tekrar denemektir. İleti işlemin yanında durur ve tekrar deneme yolunu
  içerir.
- **Kalıcı sistem hatası, kurtarılamaz.** Kullanıcının yapabileceği bir şey yok. İleti
  durumu bildirir ve başka bir yol gösterir; "tekrar deneyin" yazmaz, çünkü tekrar deneme
  işe yaramayacaktır.

Ayrımın pratik değeri iletinin içeriğini belirlemesidir. Kurtarılabilir bir hatada ileti
**kurtarma yolunu** taşımak zorundadır; taşımıyorsa kullanıcı için hata iletisi değil, yalnızca
bir engel bildirimidir. Kurtarılamaz bir hatada ise kurtarma yolu önermek yanıltıcıdır.

Uyarı, hatadan bu eksende ayrılır: uyarıda işlem sürebilir. "Bu kayıt başka şubede" bir
uyarıdır, çünkü kullanıcı yine de rezervasyon yapabilir. "Ödünç alma hakkınız doldu" bir
hatadır, çünkü işlem yapılamaz. Renk seçimi bu ayrımı izler, tersi değil.

## Doğrulama Anı İleti Sayısını Belirler

Girdi hatalarında en önemli karar, doğrulamanın **ne zaman** çalıştığıdır. Aynı doğrulama
kuralı, farklı anlarda çalıştırıldığında farklı sayıda ileti üretir.

```js
// dogrulama.mjs — dogrulama aninin uretilen hata iletisi sayisina etkisi

// ISBN-13 saglama: ilk 12 basamak 1,3,1,3... agirlikli toplanir; kontrol basamagi tumler.
function isbnGecerli(dizgi) {
  if (!/^\d{13}$/.test(dizgi)) return false;
  const b = [...dizgi].map(Number);
  let toplam = 0;
  for (let i = 0; i < 12; i++) toplam += b[i] * (i % 2 === 0 ? 1 : 3);
  return (10 - (toplam % 10)) % 10 === b[12];
}

// Bir girdinin, tamamlanmadan once gecersizligi kesin mi?
function erkenGecersiz(onek) {
  return /[^0-9]/.test(onek) || onek.length > 13;
}

const OTURUMLAR = [
  { ad: "dogru yazim",     hedef: "9789750718533" },
  { ad: "son basamak yanlis", hedef: "9789750718534" },
  { ad: "harf karisti",    hedef: "97897507I8533" },
];

for (const o of OTURUMLAR) {
  const onekler = Array.from({ length: o.hedef.length }, (_, i) => o.hedef.slice(0, i + 1));

  // 1) Her tus vuruşunda dogrula
  const herTus = onekler.filter((p) => !isbnGecerli(p)).length;
  // 2) Yalnizca kesin gecersizlikte uyar, kalanini bekle
  const erken = onekler.filter((p) => erkenGecersiz(p)).length;
  // 3) Alandan cikista dogrula
  const cikista = isbnGecerli(o.hedef) ? 0 : 1;
  // 4) Gonderimde dogrula
  const gonderimde = cikista;

  console.log(
    `${o.ad.padEnd(20)} her tus: ${String(herTus).padStart(2)}   kesin gecersizlikte: ${String(erken).padStart(2)}   ` +
      `alandan cikista: ${cikista}   gonderimde: ${gonderimde}   sonuc: ${isbnGecerli(o.hedef) ? "gecerli" : "gecersiz"}`
  );
}

// Kesin gecersizlik hangi karakterde saptanabilir?
console.log("\noturum               ilk kesin gecersiz onek uzunlugu  toplam uzunluk");
for (const o of OTURUMLAR) {
  const onekler = Array.from({ length: o.hedef.length }, (_, i) => o.hedef.slice(0, i + 1));
  const i = onekler.findIndex(erkenGecersiz);
  console.log(
    `${o.ad.padEnd(20)} ${(i === -1 ? "yok" : String(i + 1)).padStart(33)} ${String(o.hedef.length).padStart(15)}`
  );
}

// Katalog kayitlarinin ISBN alanlari gercekten gecerli mi?
console.log("\nkayit isbn      gecerli");
for (const isbn of ["9789750718533", "9789944882101", "9786055829476"]) {
  console.log(`${isbn}   ${isbnGecerli(isbn)}`);
}
```

```
dogru yazim          her tus: 12   kesin gecersizlikte:  0   alandan cikista: 0   gonderimde: 0   sonuc: gecerli
son basamak yanlis   her tus: 13   kesin gecersizlikte:  0   alandan cikista: 1   gonderimde: 1   sonuc: gecersiz
harf karisti         her tus: 13   kesin gecersizlikte:  5   alandan cikista: 1   gonderimde: 1   sonuc: gecersiz

oturum               ilk kesin gecersiz onek uzunlugu  toplam uzunluk
dogru yazim                                        yok              13
son basamak yanlis                                 yok              13
harf karisti                                         9              13

kayit isbn      gecerli
9789750718533   true
9789944882101   true
9786055829476   true
```

Birinci satır kararı tek başına veriyor. Kullanıcı ISBN'i **doğru** yazdı ve her tuş
vuruşunda doğrulayan bir arayüz ona on iki hata iletisi gösterdi. Hiçbiri yanlış değildi:
her ara adım gerçekten geçersiz bir ISBN'di. Ama hiçbiri de doğru değildi, çünkü kullanıcı
henüz yazmayı bitirmemişti.

Buradan çıkan kural şudur: **bir girdi tamamlanmadan geçersizliği kesin değilse
doğrulanmaz.** Alandan çıkışta doğrulama, doğru yazımda sıfır, yanlış yazımda bir ileti
üretiyor; istenen davranış budur.

Üçüncü satır kuralın istisnasını gösteriyor. Harf karışan oturumda geçersizlik dokuzuncu
karakterde kesinleşiyor; ondan sonra yazılacak hiçbir karakter değeri geçerli yapamaz.
Kesinleşmiş bir geçersizliği tamamlanmayı bekleyerek saklamak, kullanıcıyı dört karakter
daha boşuna yazdırmak demektir. Kural bu yüzden iki parçalıdır: kesinleşmemiş geçersizlik
beklenir, kesinleşmiş geçersizlik anında bildirilir.

Bu ayrım doğrulama kuralının biçimini de belirler. Bir alanın kuralı yalnızca "geçerli mi"
sorusunu değil, "bu önek geçerli bir değere uzayabilir mi" sorusunu da yanıtlayabilmelidir.

## En İyi Hata İletisi Gösterilmeyenidir

Bazı hatalar hata değildir; girdinin biçimsel gürültüsüdür ve arayüz onları sessizce
düzeltebilir.

```js
// kurtarma.mjs — onlenebilir hatalarin ayiklanmasi ve iletinin yerlestirilmesi

function isbnGecerli(dizgi) {
  if (!/^\d{13}$/.test(dizgi)) return false;
  const b = [...dizgi].map(Number);
  let toplam = 0;
  for (let i = 0; i < 12; i++) toplam += b[i] * (i % 2 === 0 ? 1 : 3);
  return (10 - (toplam % 10)) % 10 === b[12];
}
// Bicimsel gurultuyu temizle: bosluk, tire, uzun tire, ayrac noktalari
const normalle = (s) => s.replace(/[\s\-‐-―.]/g, "");

const GIRDILER = [
  "9789750718533",
  "978-975-07-1853-3",
  " 9789944882101 ",
  "978 605 5829 47 6",
  "9789750718534",
  "97897507I8533",
];

console.log("girdi                    ham gecerli  normalize                gecerli  sinif");
let onlenebilir = 0, gercek = 0;
for (const g of GIRDILER) {
  const n = normalle(g);
  const ham = isbnGecerli(g), son = isbnGecerli(n);
  let sinif;
  if (ham) sinif = "sorunsuz";
  else if (son) { sinif = "ONLENEBILIR"; onlenebilir++; }
  else { sinif = "gercek hata"; gercek++; }
  console.log(
    `${JSON.stringify(g).padEnd(24)} ${String(ham).padStart(11)}  ${n.padEnd(24)} ${String(son).padStart(7)}  ${sinif}`
  );
}
console.log(`\nonlenebilir hata: ${onlenebilir} / ${GIRDILER.length}   gercek hata: ${gercek} / ${GIRDILER.length}`);

// Iletinin yerlestirilmesi: yakinlik kurali (grup ici bosluk < gruplar arasi bosluk)
const ETIKET_Y = 20, ALAN_Y = 44, ILETI_Y = 18;
const GRUP_ICI = 4;      // etiket-alan ve alan-ileti araligi
const GRUPLAR_ARASI = 24; // iki alan grubu arasindaki aralik

const alanlar = ["Baslik", "Yazar", "ISBN", "Raf kodu"];
let y = 0;
const konum = {};
for (const a of alanlar) {
  konum[a] = { etiket: y, alan: y + ETIKET_Y + GRUP_ICI };
  y = konum[a].alan + ALAN_Y + GRUPLAR_ARASI;
}
console.log("\nalan       etiket y  alan y  alan alt kenari");
for (const a of alanlar) {
  console.log(`${a.padEnd(10)} ${String(konum[a].etiket).padStart(8)} ${String(konum[a].alan).padStart(7)} ${String(konum[a].alan + ALAN_Y).padStart(16)}`);
}

const hataliAlan = "ISBN";
const altKenar = konum[hataliAlan].alan + ALAN_Y;
const sonrakiEtiket = konum["Raf kodu"].etiket;
console.log(`\nileti alanin altina konursa:`);
console.log(`  iletiye uzaklik (kendi alanindan): ${GRUP_ICI} px`);
console.log(`  iletinin alt kenari: ${altKenar + GRUP_ICI + ILETI_Y} px`);
console.log(`  sonraki alanin etiketine uzaklik: ${sonrakiEtiket - (altKenar + GRUP_ICI + ILETI_Y)} px`);
console.log(`  yakinlik kurali (kendi alanina daha yakin): ${GRUP_ICI < sonrakiEtiket - (altKenar + GRUP_ICI + ILETI_Y)}`);

console.log(`\nileti formun ustunde ozet olarak konursa:`);
console.log(`  ozetten hatali alana dikey uzaklik: ${konum[hataliAlan].alan} px`);
console.log(`  arada kalan alan sayisi: ${alanlar.indexOf(hataliAlan)}`);

// Yakinlik kurali saglanmiyorsa: gruplar arasi aralik en az ne olmali?
const KAT = 3; // ileti kendi alanina, sonraki gruba gore en az bu kat daha yakin olmali
const gerekenAralik = GRUP_ICI + ILETI_Y + KAT * GRUP_ICI;
console.log(`\nileti bloguyla birlikte alanin altinda kaplanan yer: ${GRUP_ICI + ILETI_Y} px`);
console.log(`gruplar arasi aralik en az: ${gerekenAralik} px  (simdiki: ${GRUPLAR_ARASI} px)`);
console.log(`yeni aralikta sonraki etikete uzaklik: ${gerekenAralik - GRUP_ICI - ILETI_Y} px, kendi alanina ${GRUP_ICI} px, oran ${(gerekenAralik - GRUP_ICI - ILETI_Y) / GRUP_ICI}`);

// Ileti gorununce sonraki alanlar kayiyor mu? Yer ayrilirsa kaymaz.
const kayma = GRUP_ICI + ILETI_Y;
console.log(`\nileti icin yer ayrilmazsa sonraki her alan ${kayma} px asagi kayar`);
console.log(`dort alanli formda toplam kayan alan sayisi (ISBN hatali): ${alanlar.length - 1 - alanlar.indexOf("ISBN")}`);
console.log(`yer ayrilirsa kayma: 0 px, bedeli: her alanin altinda surekli ${kayma} px bos yer`);
```

```
girdi                    ham gecerli  normalize                gecerli  sinif
"9789750718533"                 true  9789750718533               true  sorunsuz
"978-975-07-1853-3"            false  9789750718533               true  ONLENEBILIR
" 9789944882101 "              false  9789944882101               true  ONLENEBILIR
"978 605 5829 47 6"            false  9786055829476               true  ONLENEBILIR
"9789750718534"                false  9789750718534              false  gercek hata
"97897507I8533"                false  97897507I8533              false  gercek hata

onlenebilir hata: 3 / 6   gercek hata: 2 / 6

alan       etiket y  alan y  alan alt kenari
Baslik            0      24               68
Yazar            92     116              160
ISBN            184     208              252
Raf kodu        276     300              344

ileti alanin altina konursa:
  iletiye uzaklik (kendi alanindan): 4 px
  iletinin alt kenari: 274 px
  sonraki alanin etiketine uzaklik: 2 px
  yakinlik kurali (kendi alanina daha yakin): false

ileti formun ustunde ozet olarak konursa:
  ozetten hatali alana dikey uzaklik: 208 px
  arada kalan alan sayisi: 2

ileti bloguyla birlikte alanin altinda kaplanan yer: 22 px
gruplar arasi aralik en az: 34 px  (simdiki: 24 px)
yeni aralikta sonraki etikete uzaklik: 12 px, kendi alanina 4 px, oran 3

ileti icin yer ayrilmazsa sonraki her alan 22 px asagi kayar
dort alanli formda toplam kayan alan sayisi (ISBN hatali): 1
yer ayrilirsa kayma: 0 px, bedeli: her alanin altinda surekli 22 px bos yer
```

Altı girdinin üçü, yalnızca ayraç taşıdığı için geçersiz görünüyor. Ayraçlar temizlendiğinde
üçü de geçerli. Bu üç girdi için hata iletisi göstermek, kullanıcıya çözebileceği bir sorun
vermez; onun zaten doğru olan girdisini reddeder.

Kural şu biçimde yazılır: **arayüzün kabul edebileceği bir girdi için hata gösterilmez.**
Ayraç, baştaki ve sondaki boşluk, büyük–küçük harf farkı bu sınıfa girer. Sessiz düzeltmenin
sınırı ise anlamı değiştirmemektir; bir basamağı düzeltmek sessizce yapılamaz, çünkü hangi
basamağın yanlış olduğu bilinmez.

## İletinin Yeri Yakınlık Kuralıyla Denetlenir

İkinci tablo grubu iletinin nereye konacağını ölçüyor ve form düzeninde bir kusur buluyor.

İleti alanın 4 piksel altına konduğunda, iletinin alt kenarı 274 pikselde bitiyor ve bir
sonraki alanın etiketi 276 pikselde başlıyor. Aradaki boşluk 2 piksel. Yakınlık ve Gruplama
dersinde kurulan kural burada ihlal ediliyor: ileti, ait olduğu alandan 4, ait olmadığı
alandan 2 piksel uzakta. Ekranda okunduğunda ileti bir sonraki alana ait görünür.

Düzeltme hesaplanabilir. İleti bloğu alanın altında 22 piksel yer kaplıyor; iletinin kendi
alanına en az üç kat daha yakın olması istendiğinde gruplar arası aralık 34 piksele
çıkmalı. Yeni aralıkta ileti kendi alanına 4, sonraki etikete 12 piksel uzaklıkta oluyor.

Form üstündeki özet, yakınlık kuralını hiç sağlamaz: özet ile hatalı alan arasında 208
piksel ve iki alan var. Bu, özetin yanlış olduğu anlamına gelmez; özet farklı bir iş yapar
— kaç hata olduğunu bildirir ve her birine bir bağlantı verir. Ancak özet, alan yanındaki
iletinin **yerini tutmaz**. İkisi birlikte kullanılır: özet sayfanın başında, ileti alanın
yanında.

Son blok bir yan etkiyi gösteriyor. İleti göründüğünde altındaki alanlar 22 piksel aşağı
kayar; bu, önceki dersteki yerleşim kayması sorununun küçük ölçekli hâlidir. Kullanıcı
iletiyi okurken tıklamak istediği alan yer değiştirir. Çözüm, ileti için baştan yer
ayırmaktır; bedeli her alanın altında sürekli duran 22 piksellik boşluktur. Bu bedel
ödenir, çünkü kayan bir formda yanlış alana tıklamak yeni bir hata üretir.

## Özet

- Hata kaynağına ve kurtarılabilirliğine göre sınıflandırılır; sınıf, iletinin içeriğini ve
  konumunu belirler.
- Kurtarılabilir hatada ileti kurtarma yolunu taşımak zorundadır; kurtarılamaz hatada
  kurtarma önermek yanıltıcıdır.
- Uyarı ile hata, işlemin sürüp süremediğine göre ayrılır; renk seçimi bu ayrımı izler.
- Tamamlanmamış bir girdi, geçersizliği kesinleşmedikçe doğrulanmaz; her tuş vuruşunda
  doğrulamak doğru yazımda bile onlarca ileti üretir. Geçersizlik kesinleştiği anda ise
  bildirilir; doğrulama kuralı "bu önek geçerli bir değere uzayabilir mi" sorusunu
  yanıtlayabilmelidir.
- Arayüzün kabul edebileceği bir girdi için hata gösterilmez; biçimsel gürültü sessizce
  temizlenir, anlam değiştiren düzeltme yapılmaz.
- İletinin konumu yakınlık kuralıyla denetlenir ve ileti için baştan yer ayrılır.

## Sonraki Adım

Hata iletisinin yanında bir simge kullanmak yaygın bir karardır ve bu ders o kararı
gerekçelendirmedi. İşlevsel Renkler dersinde renge eşlik edecek ikinci kanal olarak simge
sayılmıştı, ancak simgenin kendisi ne zaman anlam taşır, ne zaman yalnızca yer kaplar
sorusu açık kaldı. Sonraki ders simgeyi anlam taşıyan ve süsleyici olarak ikiye ayırır,
ayrımın erişilebilirlik ağacındaki karşılığını gösterir ve simgenin tek başına metnin
yerini tutup tutamayacağını tartışır.
