Hata yönetimi ve yeniden denemeler
Bir komut başarısız olduğunda, göreviniz hatayı ele almadıkça çalıştırma bir hatayla durur. Hatalara tepki vermek için try/catch/finally, kararsız adımları yeniden denemek için --retry, veriler sürecinizin bir kuralını ihlal ettiğinde bilerek durmak için throw kullanın. Bir görev hata işleyicisi görevin tamamı başarısız olduğunda bildirir ve temizlik yapar; hatada devam et ise tek tek komutların görevi durdurmadan başarısız olmasına izin verir.
try, catch ve finally
browser --action:open --url:"https://portal.example.com" --output:portal
try
capture --browser:$portal$ --action:click --dompath:"#export" --timeout:20
catch --error:err
log --message:"Export failed at line $err.CommandLine$: $err.Message$" --level:error
finally
browser --action:close --browser:$portal$
endtry
- Önce try bölümü çalışır. İçindeki bir komut başarısız olduğunda bölümün geri kalanı atlanır.
- catch bölümü, try bölümündeki bir komut başarısız olduğunda çalışır. Hata ele alınmış sayılır: bloktan sonra görev bir sonraki komutla devam eder.
- finally bölümü her zaman en sonda çalışır: başarılı bir try bölümünden sonra, catch'ten sonra, hiçbir catch'in ele almadığı bir hatadan sonra (hata daha sonra yayılmaya devam eder) ve
breakveyacontinuebloktan çıktığında. Tarayıcıları, çalışma kitaplarını ve bağlantıları burada kapatın. - Bir try için bir catch, bir finally veya her ikisi bu sırayla gerekir.
- finally içindeki bir hata (veya bir
break/continue), ondan önce olan her şeyin yerini alır. İptal edilen bir çalıştırma finally bölümünü atlar.
Düzenleyicide bölümleri paletten (Try altında), bloğun bitiş satırındaki + Catch ve + Finally düğmelerinden ya da özellikler panelindeki Sections alanından ekleyin.
Hata değişkeni
catch --error:err, hatayı err adlı bir record değişkenine koyar (istediğiniz adı seçin; özellikler panelinde Error alanıdır). Yerleşik bir hata değişkeni yoktur: --error içermeyen bir catch hatayı ele alır ama ayrıntılarını saklamaz.
| Alan | Değer |
|---|---|
$err.Message$ |
Hata mesajı |
$err.Type$ |
Business veya System (aşağıya bakın) |
$err.CommandLine$ |
Başarısız olan komutun düzenleyicide gösterilen satır numarası |
$err.CommandType$ |
Başarısız olan komut; örneğin capture veya throw |
$err.Timestamp$ |
Hatanın oluştuğu zaman |
Her catch'in yerleşik bir $error$ doldurduğu dönemde yazılmış görevler çalışmaya devam eder: açıldıklarında her catch bölümüne --error:error eklenir.
catch, mesajı ve satırı kendi değişkenlerinize de kopyalayabilir:
try
excel --action:open --file:C:\In\orders.xlsx --session:orders
catch --errormessage:problem --errorline:failedAt
log --message:"Line $failedAt$: $problem$" --level:error
endtry
İş kuralı hataları ve sistem hataları
Botream iki tür hatayı birbirinden ayırır:
| Tür | Anlamı | Örnekler | Yeniden denenir mi? |
|---|---|---|---|
| System | Uygulama, ağ veya makine başarısız oldu. Yeniden denemek işe yarayabilir. | Element bulunamadı, zaman aşımı, dosya eksik, bağlantı reddedildi | Evet |
| Business | Sürecinizin bir kuralı ihlal edildi. Yeniden denemek hiçbir şeyi değiştirmez. | Faturanın toplamı yok, müşteri bilinmiyor, onay eksik | Hayır |
Bir komutun oluşturduğu her hata bir sistem hatasıdır. throw ile oluşturduğunuz hatalar, aksini belirtmediğiniz sürece iş kuralı hatasıdır. Çağrılan bir görevin hatası runtask üzerinden türünü korur.
Tür, bundan sonra ne olacağını belirler:
--retryyalnızca sistem hatalarını yineler.loop --type:queueiçinde, bir sistem hatasıyla başarısız olan tur, iş öğesini başka bir deneme için geri koyar (kuyruk yeniden denemelere izin verdiği sürece); bir iş kuralı hatası ise öğeyi kalıcı olarak başarısız sayar. Bkz. İş kuyrukları.- Çalıştırma sayfası başarısız bir çalıştırmayı Business rule veya System error olarak gösterir.
Yalnızca bir türü ele alma
catch --errortype:business (veya system) yalnızca o türdeki hataları ele alır. Diğer tür, aradaki finally bölümleri çalıştıktan sonra dıştaki bir catch'e geçer.
try
runtask --name:BookInvoice --invoiceNo:$row.No$
catch --error:err --errortype:business
log --message:"Skipped invoice $row.No$: $err.Message$" --level:warning
endtry
throw ile hata oluşturma
throw, normal akışı kendi oluşturduğunuz bir hatayla durdurur. Hatayı en yakın catch ele alır; catch yoksa çalıştırma sizin mesajınızla başarısız olur.
if --condition:$total$ <= 0
throw --message:"Invoice $no$ has no total"
endif
if --condition:$response.StatusCode$ = 503
throw --message:"The booking service is unavailable" --type:system
endif
--type:businessvarsayılandır; kendiniz tespit ettiğiniz teknik hatalar için--type:systemkullanın, böylece yeniden denemeler ve kuyruklar onları buna göre ele alır.--messagezorunludur; ancak catch bölümü içinde mesajsızthrow, yakalanan hatayı mesajını ve türünü koruyarak dışarıdaki bir sonraki catch'e iletir.
try
database --action:execute --session:erp --query:"UPDATE Orders SET Status='Booked' WHERE Id=@id" --params:id=$id$
catch --error:err
log --message:"Booking failed: $err.Message$" --level:error
throw
endtry
Bir komutu yeniden deneme
Geçici sorunlar kendiliğinden yeniden denenir
Ekranlarla ve dosyalarla çalışan komutlar (capture, desktop, image, sap, mouse, sendkeys, browser, window, excel, csv, pdf, file, folder, zip, xml, json), kendiliğinden geçen bir nedenle başarısız olduklarında 1,5 saniye sonra bir kez daha dener:
- sayfa kullanılırken yükleniyor veya yeniden çiziliyordu (öğe bir anlığına sayfadan çıktı);
- bir yükleniyor katmanı ya da dönen simge öğeyi örtüyordu;
- dosyayı başka bir program açık tutuyordu;
- bir masaüstü öğesi yeniden oluşturuluyordu.
Günlük bunu belirtir ("A passing problem: … Trying once more") ve işe yaradığında "The second try worked" yazar. İki kez olmaması gereken eylemler (tıklamalar, tuş basmaları, seçimler, yüklemeler) yalnızca sorun bu eylemin hiç gerçekleşmediğini gösterdiğinde (hedef örtülüydü veya yoktu) yeniden denenir. Bulunamayan bir öğe yeniden denenmez: komut onu zaten --timeout süresince bekledi; değişen öğeleri kendi kendini iyileştirme ele alır. mail, restapi ve database kendiliğinden yeniden denenmez, çünkü istekleri karşı tarafa ulaşmış olabilir; tekrarlamak güvenliyse onlara --retry verin.
--retry:0 bir komut için otomatik denemeyi kapatır; başka herhangi bir --retry onun yerine geçer.
--retry
Şu komutlar --retry (ek deneme sayısı) ve --retryinterval (denemeler arasındaki saniye, varsayılan 1) kabul eder:
| Komut | Tipik kullanım |
|---|---|
capture |
Geç görünen bir web elementi veya yavaş bir sayfa |
desktop |
Henüz hazır olmayan bir masaüstü elementi |
database |
Zaman zaman başarısız olan bir bağlantı veya sorgu |
mail |
Bağlantıyı reddeden bir posta sunucusu |
restapi |
Zaman aşımına uğrayan veya hatayla yanıt veren bir hizmet |
ai |
Meşgul bir yapay zekâ modeli |
file --action:wait |
Hâlâ yazılmakta olan bir dosya |
runtask |
Teknik bir nedenle başarısız olan çağrılmış bir görev |
restapi --action:post --url:"https://api.example.com/bookings" --body:$booking$ --output:response --retry:3 --retryinterval:5
capture --browser:$shop$ --action:click --dompath:"#checkout" --retry:2 --retryinterval:2
Her başarısız deneme günlüğe bir uyarı yazar ("Attempt 1 of 4 failed: … Retrying in 5s"). Son deneme de başarısız olduğunda komut kendi hatasıyla başarısız olur; bu hatayı bir catch ele alabilir. İş kuralı hataları asla yeniden denenmez.
İpucu: Web ve masaüstü komutları elementleri için zaten
--timeoutsaniyeye kadar (varsayılan 30) bekler.--retryseçeneğini kısa bir zaman aşımını uzatmak için değil, sonraki bir denemenin giderebileceği hatalar için kullanın.
Bir komut grubunu yeniden deneme
--retry tek bir komutu yineler. Bir portala oturum açmak ve bir sayfayı açmak gibi birlikte iş gören birkaç komut için onları bir retry bloğuna koyun (UiPath'teki Retry Scope): içlerinden biri başarısız olduğunda blok bekler ve hepsini baştan yeniden çalıştırır.
retry --times:3 --interval:5
browser --action:open --url:"https://portal.example.com" --output:portal
capture --browser:$portal$ --action:click --dompath:"#login"
wait --type:element --browser:$portal$ --dompath:"#dashboard" --failontimeout:true
endretry
| Parametre | Varsayılan | Anlamı |
|---|---|---|
--times |
3 | İlki dahil toplam deneme sayısı |
--interval |
1 | Bir sonraki denemeden önce beklenecek saniye |
--until |
– | Komutlar çalıştıktan sonra doğru olması gereken bir koşul (if --condition gibi yazılır); yanlış olduğu sürece blok yeniden dener |
retry --times:10 --interval:30 --until:"$status$ = Ready"
restapi --action:get --url:"https://api.example.com/jobs/$jobId$" --output:job
set --name:status --value:$job.Json.status$
endretry
- Her yeni deneme günlüğe hatayı ve satırını içeren bir uyarı yazar: "Attempt 2 of 3 after: …".
- Son deneme de başarısız olursa hata olağan şekilde devam eder: bloğun çevresindeki bir
tryonu yakalar, yoksa çalıştırma başarısız olur.--untilile, son denemeden sonra hâlâ yanlış olan koşul bloğu başarısız kılar ("The retry condition was still false after 10 attempts"). - İş kuralı hataları (
throw) ve eylemin zaten gerçekleşmiş olabileceği hatalar (sunucunun almış olabileceği bir e-posta) yeniden denenmez; hata hemen devam eder. - Bloğun içindeki
breakvecontinuebloktan hemen çıkar;stoptaskve çalıştırmayı durdurmak da öyle. - Hata ayıklarken çalıştırma yalnızca son denemenin hatasında durur; Step into bloğun içine girer.
- İçerideki komutlar önce kendi
--retryayarlarını (ve otomatik ikinci denemeyi) kullanır.
Düzenleyicide Retry komutunu paletten (Error Handling) ekleyin, komutları içine bırakın ve deneme sayısını özelliklerinden ayarlayın. Retry bloğu güncel ajanı gerektirir: böyle bir görev eski bir ajana gönderilmez ve çalıştırma, ajanı güncellemenizi söyleyen bir iletiyle reddedilir.
Görev hata işleyicisi
Üretimdeki bir robot öylece durmamalıdır: bir şeyler ters gittiğinde birine haber vermeli, iş öğesini işaretlemeli ve kullandığı uygulamayı kapatmalıdır. Görevin tamamını bir try içine almak yerine bir görev hata işleyicisi ekleyin (UiPath'teki Global Exception Handler, Automation Anywhere'deki hata işleyici). Yalnızca hiçbir catch bloğunun ele almadığı bir hata görevi başarısız kılmak üzereyken çalışır:
onerror --error:err
log --message:"Failed at line $err.CommandLine$ ($err.CommandType$): $err.Message$" --level:error
screenshot --file:"C:\Botream\Errors\$System.ExecutionId$.png" --onerror:continue
mail --action:send --smtp:smtp.company.com --port:587 --from:robot@company.com --to:support@company.com --subject:"Robot failed: $System.TaskName$" --body:$err.Message$ --onerror:continue
window --action:close --window:$erp$ --onerror:continue
endonerror
- Onu görevin sonuna, ana seviyeye koyun. Bir görevin tek bir hata işleyicisi olur; normal akışta hiçbir zaman çalışmaz.
--error, hatayı alacak record değişkeninin adıdır (varsayılanerror); alanları catch'tekiyle aynıdır:$err.Message$,$err.Type$,$err.CommandLine$,$err.CommandType$,$err.Timestamp$.--then, işleyiciden sonra çalıştırmanın nasıl biteceğini belirler:fail(varsayılan) — çalıştırma, işleyici yokmuş gibi özgün hatayla başarısız olur;complete— hata ele alınmış sayılır ve çalıştırma günlükte bir uyarıyla Completed olarak biter.completeseçeneğini yalnızca "ele alındı" bildirmesi gereken görevlerde kullanın; örneğin işleyici işi zaten geri koyduysa.- Başarısız çalıştırmanın ekran görüntüsü ve değişkenleri işleyici çalışmadan önce alınır; böylece çalıştırma sayfası ekranı işleyicinin uygulamayı kapattıktan sonraki haliyle değil, hata anındaki haliyle gösterir. İşleyici çalışırken tarayıcılar ve oturumlar hâlâ açıktır.
- İşleyicinin içindeki bir hata günlüğe yazılır ve çalıştırma özgün hatayla başarısız olur; işleyici ikinci kez çalışmaz. Başarısız olan bir temizlik adımının diğerlerini atlatmaması için komutlarına
--onerror:continueverin (aşağıya bakın). - Bir
catchbloğunun ele aldığı hatalarda,loop --type:queuedöngüsünün başarısız turlarında (döngü bunları kendisi ele alır),stoptaskile ve çalıştırma durdurulduğunda ya da iptal edildiğinde (web uygulamasından, tepsi uygulamasından veya ajan kapandığı için) çalışmaz. Zaman aşımına uğrayan bir komut (--timeout,wait --failontimeout:true) diğer komutlar gibi başarısız olur; bu durumda işleyici çalışır. - Çağrılan görevler (
runtask): her görevin kendi işleyicisi kendi hatalarını ele alır. Ardından hata olağan şekilde çağıran göreve geçer (oradaki bir catch veya çağıranın işleyicisi onu ele alır); çağrılan görevin işleyicisi--then:completediyorsa geçmez ve çağrılan görev normal şekilde döner. - İş kuyrukları: bir çalıştırma bittiğinde sunucu, işlemekte olduğu öğeyi kuyruğa geri koyar (yeniden deneme hakkı kalmadıysa başarısız sayar). Öğeyi bir nedenle kalıcı olarak başarısız saymak için işleyiciye
queue --action:fail --item:$item$ --reason:$err.Message$ekleyin. - Hata ayıklama: Stop at errors no catch handles açıkken hata ayıklama çalıştırması önce başarısız olan komutta durur; Continue ardından işleyiciyi çalıştırır, burada kesme noktaları her zamanki gibi çalışır.
Düzenleyicide Task error handler komutunu paletten (Error Handling) veya Ctrl+K ile ekleyin: nereye bırakırsanız bırakın her zaman görevin sonuna yerleşir; kartı kırmızı tonludur ve Yalnızca görev başarısız olursa işaretini taşır. Özellikleri Error ve Then alanlarıdır.
Başarısız bir komuttan sonra devam etme
Bazı komutlar zarar vermeden başarısız olabilir: var olmayan geçici bir dosyayı silmek, zaten kapanmış bir pencereyi kapatmak, bir bildirim göndermek. Her birinin çevresine bir try bloğu koymak yerine komutun isteğe bağlı ayarlarında Hata olursa seçeneğini Sonraki komutla devam et yapın (--onerror:continue):
file --action:delete --path:"C:\Temp\export.csv" --onerror:continue --errorto:deleteError
if --condition:"$deleteError$ != null"
log --message:"Could not delete the export: $deleteError.Message$" --level:warning
endif
- Önce komutun kendi yeniden denemeleri (
--retryve otomatik ikinci deneme) yapılır. Komut yine başarısız olursa günlüğe bir uyarı yazılır ("Line 1 (file) failed and the task goes on (--onerror:continue): …") ve görev bir sonraki komutla devam eder. --errorto(Hatayı şuraya kaydet), hatayı catch'in hata değişkeniyle aynı alanlara sahip bir record olarak saklar. Komut başarılı olduğunda değişken boştur (null); böylece bir döngüde önceki turun hatasını görmezsiniz.- Varsayılan Görevi durdur (
--onerror:stop) seçeneğidir: bir catch veya görev hata işleyicisi ele almadıkça hata görevi durdurur. - Bloklar (if, loop, try, switch, retry, step ve görev hata işleyicisi) ile
comment,input,output,break,continuevethrowdışındaki her komutta kullanılabilir. Bir komut grubu için birtrybloğu kullanın. - Komutun ardından devam ettiği bir hata ele alınmış sayılır: hata ayıklayıcı orada durmaz ve görev hata işleyicisi çalışmaz.
- Blok düzenleyicide böyle bir komut Hatada devam eder işaretini gösterir.
Görev hata işleyicisi ve hatada devam et güncel ajanı gerektirir: böyle bir görev eski bir ajana gönderilmez ve çalıştırma, ajanı güncellemenizi söyleyen bir iletiyle reddedilir.
Zaman aşımına uğrayan beklemeler
wait, süresi dolduğunda başarısız olmaz: bir uyarı günlüğe yazar, görev devam eder ve --output değeri false olur. Başarısız olmasını, böylece bir catch'in onu ele almasını sağlamak için --failontimeout:true ekleyin.
wait --type:fileexists --path:C:\In\*.csv --timeout:300 --failontimeout:true
Mesajlar ve istemler
Ajan makinesinde bir prompt penceresinin iptal edilmesi komutu başarısız kılar. Kişinin iptal edebileceği durumlarda onu try/catch içine alın.
Bir çalıştırma başarısız olduğunda
Hiçbir catch'in ele almadığı bir hata bir çalıştırmayı sonlandırdığında, ajan tarayıcıları ve oturumları kapatmadan önce bir anlık görüntü saklar. Çalıştırma sayfası şunları gösterir:
- başarısız olan satır ve komutla birlikte hata mesajı ve hatanın Business rule mı yoksa System error mı olduğu;
- Screen when the task failed: ajan makinesinin o andaki ekran görüntüsü (tam boyut için tıklayın);
- Variables at the failure: görevin tüm değişkenleri; parolalar maskelenmiş ve uzun değerler kısaltılmış olarak.
Hata çağrılan bir görevin içinde oluştuğunda, anlık görüntü çağrılan görevin, yani hatanın gerçekten oluştuğu yerin görüntüsüdür. Görevin bir hata işleyicisi varsa anlık görüntü işleyici çalışmadan önce alınır.
Yapay zekâ ile hata analizi
Bir yapay zekâ modeli ayarlandığında, başarısız bir çalıştırmadaki Analyze with AI; hatadan, başarısız komuttan, günlükten ve değişkenlerden (parolalar dışarıda bırakılır) yola çıkarak ne olduğunu, olası nedenini ve nasıl düzeltileceğini açıklar. Yanıt çalıştırmayla birlikte saklanır. Bkz. Yapay zekâ özellikleri.
Hata ayıklarken hatalarda durma
Bir hata ayıklama çalıştırmasında Stop at errors no catch handles (varsayılan olarak açık), çalıştırmayı başarısız komutta duraklatır; böylece çalıştırma başarısız olmadan önce değişkenlere bakabilirsiniz. Bkz. Hata ayıklama.
İyi uygulamalar
- Tarayıcıları, Excel oturumlarını ve veritabanı bağlantılarını
trybloğundan hemen önce açın vefinallyiçinde kapatın; böylece bir hatadan sonra bile kapatılırlar (finally içinde hiç açılmamış bir şeye başvuran bir kapatma işleminin kendisi başarısız olur). - Hatalı veriler için iş kuralı hataları oluşturun ve bunları yeniden denemelerin dışında tutun; teknik hatalar sistem hatası olarak kalsın.
- Zaman zaman başarısız olan adımları (oturum açma, sayfayı açma) bütün olarak bir
retrybloğuna alın; tüm denemeler başarısız olduğunda ne yapılacağı için de çevresine birtrykoyun. - catch bölümlerinde hataya bir ad verin (
catch --error:err) ve$err.Message$ile$err.CommandLine$değerlerini günlüğe yazın; satır numarası düzenleyiciyle eşleşir. - Çok sayıda öğe üzerindeki döngülerde, hatalı tek bir öğenin tüm işi durdurmaması için try bloğunu döngünün içine koyun ya da her öğenin hatasını sizin için ele alan
loop --type:queuekullanın. - Gözetimsiz çalışan her göreve hatayı günlüğe yazan, birine haber veren ve uygulamaları kapatan bir görev hata işleyicisi ekleyin; temizlik komutlarına
--onerror:continueverin. --onerror:continueseçeneğini yalnızca başarısız olması gerçekten önemsiz olan komutlarda kullanın; önemliyse hatayı bir catch ile ele alın.