Aspnetcore: Penanganan pengecualian global

Dibuat pada 26 Agu 2019  ·  51Komentar  ·  Sumber: dotnet/aspnetcore

Halo teman-teman, saya ingin tahu apa cara yang lebih baik untuk menangkap pengecualian di tingkat aplikasi, untuk menghindari try catch di semua metode dan komponen saya, dan memusatkan manajemen pengecualian di satu titik (biasanya menampilkan pemberitahuan kesalahan dan mencatat pengecualian) .

jadi ada cara yang lebih baik untuk melakukan ini di preview8, atau sesuatu yang direncanakan untuk RTM?

Terima kasih !

Components Big Rock affected-most area-blazor enhancement severity-major

Komentar yang paling membantu

Setiap pembaruan tentang masalah ini?

Saat ini aplikasi blazer sisi server saya baru saja berhenti merespons input pengguna setelah pengecualian dilemparkan.

Ini bukan praktik yang baik untuk mencakup semua baris kode dengan try-catch (atau mengharapkan pengembang untuk melakukannya), dalam kasus pengecualian "tidak diprediksi" kita harus memiliki penangan generik yang memungkinkan kita:

1.Pilih apakah akan memutus sirkuit.
2.Tampilkan pesan GUI "ramah" kepada pengguna kami atau arahkan saja dia ke halaman kesalahan umum.

Saat ini setelah pengecualian yang tidak tertangani, aplikasi tidak dapat memberi tahu pengguna tentang suatu masalah dan pengguna hanya dapat menjalankan kembali aplikasi (menutup browser dan membuka URL aplikasi lagi) atau menyegarkan halaman dan kehilangan semua status (yang terkadang bagus , tetapi pengembang aplikasi harus memilih ini).

Semua 51 komentar

Semua pengecualian yang tidak tertangani harus berakhir di Logger. Jika Anda melihat sebaliknya, beri tahu kami dan kami akan dengan senang hati menyelidikinya. Melihat log harus menjadi cara untuk pergi ke sini.

Oke, yang saya pahami adalah saya harus menyediakan implementasi ILogger saya sendiri? dan pada implementasi saya, saya harus berurusan dengan pengecualian? (misalnya tampilkan pemberitahuan, tulis pengecualian dalam file untuk sisi server dan kirimkan ke pengontrol untuk sisi klien)
sebenarnya satu-satunya hal yang ditemukan adalah paket ini https://github.com/BlazorExtensions/Logging
Saya tidak begitu mengerti cara menggunakannya, sepertinya kita hanya bisa masuk ke konsol dengan ini.

Tetapi bahkan dengan ekstensi ini, jika ada pengecualian yang tidak tertangani dalam kode, aplikasi akan mogok.

jadi jika saya mengerti, saya tidak punya pilihan untuk mengelilingi semua kode saya dengan try catch ?

terima kasih atas penjelasannya

Penyedia logger mana pun yang tercantum di sini: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2#built -in-logging-providers sebagai juga penyedia yang dikembangkan komunitas ( https://github.com/aspnet/Extensions/tree/master/src/Logging#providers) akan berfungsi.

Tetapi bahkan dengan ekstensi ini, jika ada pengecualian yang tidak tertangani dalam kode, aplikasi akan mogok.

Untuk Blazor sisi server, pengecualian yang tidak ditangani harus memutuskan sirkuit, tetapi tidak membuat aplikasi mogok. Jika sebuah blok dimaksudkan untuk mengeluarkan pengecualian yang dapat Anda toleransi, try-catch sepertinya cara yang paling masuk akal untuk melanjutkan. Apa yang Anda rencanakan untuk dilakukan dengan pengecualian yang tidak ditangani jika Anda menangkap pengecualian sewenang-wenang?

Blazor sisi klien tidak mencatat pengecualian apa pun. Mereka hanya dicetak ke konsol. Berikut adalah kode dari WebAssemblyRenderer

protected override void HandleException(Exception exception)
{
    Console.Error.WriteLine($"Unhandled exception rendering component:");
    if (exception is AggregateException aggregateException)
    {
        foreach (var innerException in aggregateException.Flatten().InnerExceptions)
        {
            Console.Error.WriteLine(innerException);
        }
    }
    else
    {
        Console.Error.WriteLine(exception);
    }
}

Satu-satunya cara saya menemukan bahwa dapat mencegat pengecualian dijelaskan di sini
https://remibou.github.io/Exception-handling-in-Blazor/

Tapi saya tidak akan menyebut penanganan pengecualian ini ...

Saya ingin memiliki penangan pengecualian global sehingga saya dapat menulis kode saya tanpa blok tangkap...

{
   IsLoading = true;
   await SomeAsync();
}
finally
{
   IsLoading = false;
   //force rerender after exception
    StateHasChanged();
}

Jika metode SomeAsync memberikan pengecualian, varialbe IsLoading saya disetel ke false tetapi tampilan saya tidak dirender. Anda harus memanggil SetStateHasChanged di blok akhirnya untuk memaksa tampilan rerender

untuk blazor sisi klien, saya akhirnya menulis implementasi saya sendiri di ILogger (terinspirasi oleh kode implementasi default yang masuk ke konsol).
Dengan implementasi ini, saya dapat memanggil LoggerController di server saya, yang juga disuntikkan ILogger (tapi kali ini, ini adalah implementasi NLog yang disuntikkan, jadi saya bisa menulis semua pengecualian dengan benar di server)

Saya mengabaikan gagasan penanganan pengecualian global, yang tampaknya bukan logika blazer, dan meletakkan try/catch di mana-mana dan menyuntikkan ILoggerdi semua komponen.

Kecuali jika menurut Anda ada yang lebih baik untuk dilakukan, Anda dapat menutup masalah ini.

Saya pikir ini adalah fitur yang hilang .. Ketika pengecualian dilemparkan, saya juga ingin memiliki tempat terpusat untuk menangkap semua pengecualian yang tidak tertangani dan melakukan sesuatu .. Menampilkannya dalam sembulan, mencatatnya di suatu tempat, mengirimkannya ke server atau apa pun .. tanpa membahayakan status aplikasi
Sesuatu seperti acara UnhandledException di WPF
https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netframework-4.8

Bukankah ILogger sudah menjadi tempat yang terpusat?

@SteveSandersonMS lihat komentar saya di atas
https://github.com/aspnet/AspNetCore/issues/13452#issuecomment -535227410
Pengecualian (dalam blazor sisi klien) ditulis ke konsol menggunakan Console.Error.WriteLine, mereka tidak dicatat menggunakan ILogger.. Anda dapat menerapkan TextWriter khusus dan mengganti Console.Error
https://remibou.github.io/Exception-handling-in-Blazor/
tetapi Anda mendapatkan representasi string dari pengecualian.. Mengurai string itu, yang menyertakan jejak tumpukan, dan mencoba untuk mendapatkan (misalnya) hanya pesan pengecualian yang paling tidak rumit untuk dikatakan.
Saya ingin mendapatkan akses ke objek pengecualian sehingga saya dapat melakukan pencatatan sendiri (atau apa pun)

@rborosak Terima kasih atas klarifikasinya!

Setiap pembaruan tentang masalah ini?

Saat ini aplikasi blazer sisi server saya baru saja berhenti merespons input pengguna setelah pengecualian dilemparkan.

Ini bukan praktik yang baik untuk mencakup semua baris kode dengan try-catch (atau mengharapkan pengembang untuk melakukannya), dalam kasus pengecualian "tidak diprediksi" kita harus memiliki penangan generik yang memungkinkan kita:

1.Pilih apakah akan memutus sirkuit.
2.Tampilkan pesan GUI "ramah" kepada pengguna kami atau arahkan saja dia ke halaman kesalahan umum.

Saat ini setelah pengecualian yang tidak tertangani, aplikasi tidak dapat memberi tahu pengguna tentang suatu masalah dan pengguna hanya dapat menjalankan kembali aplikasi (menutup browser dan membuka URL aplikasi lagi) atau menyegarkan halaman dan kehilangan semua status (yang terkadang bagus , tetapi pengembang aplikasi harus memilih ini).

@hagaygo Ringkasan yang sangat bagus!

@SteveSandersonMS Harap pertimbangkan ini untuk pencapaian 3.1.x! Tolong jangan pindahkan ini ke 5.0.0

Hai,

Saya mendapatkan kesalahan semacam ini ketika sirkuit rusak di Konsol Jendela Pengembang .

image

Saya tidak berpikir ada saat ini yang dapat memberi tahu pengguna bahwa kesalahan telah terjadi setelah ini di layar dan meminta untuk menyegarkannya tanpa membuka jendela pengembang secara manual untuk memeriksa dan menyegarkan halaman

@SteveSandersonMS Bisakah Anda mengklarifikasi apakah app.UseExceptionHandler() berfungsi untuk blazer sisi server atau tidak?

Saya telah melihat beberapa kasus di mana kebiasaan saya ErrorHandler tidak menangkap pengecualian yang dilemparkan oleh aplikasi saya. Contoh kode

Startup.cs :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
    ...
    app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = ErrorHandler.HandleError });
    ...
}

ErrorHandler.cs :

public static async Task HandleError(HttpContext context)
{
    var error = context.Features.Get<IExceptionHandlerFeature>()?.Error;
    var message = error?.Message ?? "[EXCEPTION NOT FOUND]";        
    return;
}

Contohnya adalah ketika repositori saya melempar pengecualian seperti itu:
The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

Solusi MVC saya menangkap semua pengecualian dan menggunakan implementasi ErrorHandling yang serupa.

Memindahkan ini ke rilis 5.0 untuk menyaring pertanyaan spesifik di sini dan melihat apakah kami dapat mengatasi beberapa di antaranya.

masalah terbesar bagi saya adalah batas kesalahan . saya ingin dapat menggunakan komponen pihak ketiga dan, entah bagaimana, membungkus penggunaan komponen itu dalam penanganan kesalahan sehingga bug di perpustakaan tidak mematikan seluruh aplikasi web saya. saat ini tidak ada "tempat untuk meletakkan tangkapan percobaan" - seluruh komponen pohon diawasi oleh penyaji blazer, yang akan mati jika ada sesuatu di dalam pohon yang rusak.

+1 untuk fitur ini.
Harus meletakkan blok coba/tangkap di semua metode bukanlah cara yang masuk akal.

Saya pribadi biasa membuang pengecualian untuk mengelola kesalahan bisnis. Pada tingkat tinggi, saya menangkap pengecualian dan menurut jenisnya, saya memutuskan apakah pengecualian harus dicatat, ditampilkan kepada pengguna dan jika ditampilkan jika saya menampilkan pesan lengkap (pengecualian bisnis) atau hanya "Ada yang salah") .

Sebenarnya, satu-satunya cara yang saya temukan untuk melakukan sesuatu seperti ini adalah dengan membuat kelas ComponentBaseEx yang mewarisi ComponentBase dan menimpa OnInitialized(Async), OnParametersSet(Async), ...
Sayangnya, bahkan dengan cara ini, saya harus mengelola semua tindakan pengguna secara manual (menghapus pelanggan, ...)

Menurut mu
1) sesuatu yang bisa dilakukan?
2) jika ya, kapan?

Inilah skenario saya: Aplikasi desktop/hibrida Blazor menggunakan server Blazor. Satu pengguna masuk pada satu waktu dan status tetap ada di seluruh pemuatan ulang. Jadi, jika ada pengecualian yang tidak tertangani, tidak ada cara untuk mengembalikan aplikasi ke status tepercaya selain memulai ulang. Kita perlu menangkap pengecualian yang tidak tertangani, menunjukkan UX yang sesuai, dan kemudian mematikan. Pola aplikasi desktop standar.

Peretasan sementara: kami telah menyiapkan logging dengan Serilog. Serilog memiliki API yang memungkinkan Anda memfilter semua pesan log dan memutuskan apakah pesan tersebut dipancarkan. Kami menyalahgunakan API ini dengan memeriksa apakah peristiwa log memiliki kunci CircuitId di kamus propertinya. Jika ya, itu berarti sirkuit telah mati - yaitu, ada pengecualian yang tidak tertangani. Kita bisa mendapatkan pengecualian yang menyinggung dari objek pesan log yang kita periksa. Presto - Anda memiliki pengecualian yang tidak tertangani di bagian paling atas dan dapat melakukan apa pun yang Anda inginkan dengannya.

Halo teman-teman, seperti yang lain, saya benar-benar khawatir jika Anda memindahkan ini ke tonggak .NET 5.
Setelah satu tahun mengerjakan blazor dengan menulis ulang aplikasi lama, saya kira saya akan menerapkan aplikasi saya dalam produksi pada bulan Mei/Juni (ketika webasssembly akan siap produksi).

Tetapi saya pasti tidak dapat melakukannya tanpa cara yang kuat untuk menangkap atau setidaknya mencatat semua kesalahan yang tidak terduga.

Harap pertimbangkan untuk membuat sesuatu, bahkan tidak sempurna, sebelum rilis 5.0 (hanya metode dengan pengecualian yang OK untuk saya, setidaknya kita bisa masuk ...)

Terima kasih banyak!

Halo, saya dalam situasi yang sama dengan @julienGrd
Tolong lakukan sesuatu untuk membantu/membimbing kami.
Salam!

Sama halnya dengan saya.

Kami telah menggunakan sisi Server Blazor untuk semua pengembangan kami dan bermigrasi dari
Halaman Web ASP.Net warisan.

Pada Selasa, 3 Maret 2020 pukul 12:02 eliudgerardo [email protected]
menulis:

Halo, saya dalam situasi yang sama dengan @julienGrd
https://github.com/julienGrd
Tolong lakukan sesuatu untuk membantu/membimbing kami.
Salam!


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/dotnet/aspnetcore/issues/13452?email_source=notifications&email_token=ANKYSDFSUQ3OTBGWQMRV5EDRFUZ27A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WZ56
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/ANKYSDGFCDRMZV2N4NLMOMLRFUZ27ANCNFSM4IPQWA6Q
.

--
Ankit Bansal

*Permainan Ilmiah*

Tujuannya adalah agar Anda dapat mencatat semua pengecualian yang tidak tertangkap menggunakan antarmuka ILogger . Ini berarti Anda dapat memasang sistem logging kustom Anda sendiri yang melakukan apa pun yang Anda inginkan dengan pengecualian info.

Namun masih ada bagian yang belum kami terapkan. Ini sedang dilacak oleh https://github.com/dotnet/aspnetcore/issues/19533. Kami pasti akan menyelesaikan ini segera.

Anda harus dapat mencatat semua pengecualian yang tidak tertangkap menggunakan antarmuka ILogger

@SteveSandersonMS Saya pikir apa yang kami kejar di sini adalah API yang jauh lebih umum, yang hanya memberi Anda pengecualian yang tidak tertangkap untuk melakukan apa pun yang kami inginkan _dengan pengecualian itu sendiri._ Bayangkan kami ingin memeriksa pengecualian dan mungkin bereaksi entah bagaimana, mungkin mengirim pengecualian untuk layanan pelacakan pengecualian seperti Raygun, atau menyajikan beberapa UI berdasarkan konten. Tanpa API seperti itu, kita perlu menyalahgunakan antarmuka ILogger untuk menyelesaikan semua hal ini, yang terasa canggung. Mengapa tidak menyediakan API yang jauh lebih umum itu, daripada memaksakan semua skenario yang mungkin melalui implementasi ILogger?

Tujuannya adalah agar Anda dapat mencatat semua pengecualian yang tidak tertangkap menggunakan antarmuka ILogger . Ini berarti Anda dapat memasang sistem logging kustom Anda sendiri yang melakukan apa pun yang Anda inginkan dengan pengecualian info.

@SteveSandersonMS Apakah Anda memiliki contoh referensi untuk melakukan ini di aplikasi Server Side Blazor? Niat saya adalah setelah mencatat pengecualian yang tidak tertangkap, tunjukkan pesan ramah kepada pengguna. Bantuan akan dihargai. Salam.

@eliudgerardo Blazor Server sudah menampilkan beberapa UI yang dihadapi pengguna saat ada kesalahan yang tidak tertangani. Anda dapat menyesuaikan UI ini. Dokumen tentangnya ada di https://docs.microsoft.com/en-us/aspnet/core/blazor/handle-errors?view=aspnetcore-3.1#detailed -errors-during-development

@SteveSandersonMS Saya mengetahui opsi yang Anda sebutkan, tetapi saya khawatir dalam hal ini Sirkuit koneksi rusak, dan saya tidak ingin membungkus semua panggilan API saya dengan try/catch. Jadi apakah ada cara untuk mencapai itu?

@eliudgerardo Mengapa penting sirkuitnya rusak? Apakah tujuan Anda entah bagaimana membiarkan pengguna terus menggunakan sirkuit bahkan setelah pengecualian yang tidak tertangani?

@SteveSandersonMS Kami tidak ingin sirkuit putus!. Jika pengecualian terjadi (di aplikasi kami atau di suatu tempat di perpustakaan pihak ketiga yang kami gunakan), kami ingin tempat di mana kami dapat menampilkan dialog yang mengatakan "Ada yang tidak beres {exception.Message}" dan aplikasi akan terus bekerja. Kami memiliki solusi parsial untuk ini, bungkus metode siklus hidup dan metode kami ke dalam blok coba tangkap tetapi itu rumit dan ada masalah dengan perpustakaan pihak ketiga ...

@partyelite Jika pengecualian tidak ditangani, maka sirkuit itu sekarang dalam keadaan tidak diketahui. Kami tidak bisa lagi mengatakan apakah ada sumber daya di dalamnya yang masih dapat digunakan, apakah logika keamanan Anda telah dijalankan sepenuhnya, atau apa pun. Jika sirkuit terus digunakan, itu dapat membuat perilaku tidak terdefinisi termasuk potensi masalah keamanan, yang bermasalah karena kode ini berjalan di server Anda.

Satu kemungkinan yang kami pertimbangkan untuk masa depan adalah memiliki mekanisme opsional "per component unhandled exception". Jika mekanisme ini diaktifkan, maka framework akan melakukan logika try/catch sendiri di sekitar semua panggilan ke dalam metode siklus hidup komponen, event handler, dan logika rendering. Jika kerangka kerja menangkap pengecualian pada tingkat itu, itu akan menganggap bahwa komponen individu mati (dan mungkin menggantinya di UI dengan semacam komponen "kesalahan") tetapi tidak akan memengaruhi eksekusi rangkaian lainnya.

Apakah menurut Anda pendekatan semacam itu akan memenuhi kebutuhan Anda?

Saya tentu menyukai gagasan memiliki batas komponen bawaan untuk kesalahan.

Itu akan sangat baik. Tapi saya pikir kita masih memerlukan metode (yang memiliki pengecualian yang terjadi sebagai parameter input) yang dapat kita timpa dan melakukan sesuatu dengan pengecualian itu - seperti menampilkan dialog dengan detail pengecualian atau mengirim detail pengecualian ke server tempat ia akan login DB atau apa..
Saya tahu bahwa hal serupa sekarang dapat dilakukan menggunakan ILogger tetapi kami mendapatkan string sebagai parameter input dan mendapatkan beberapa data spesifik dari pengecualian dalam format string sangat sulit.

jebakan pengecualian tidak tertangani per komponen akan sangat bagus. idealnya ini adalah sesuatu yang dapat ditentukan secara eksternal dan/atau dalam komponen tertentu, sehingga kami dapat memisahkan bagian dari ui atau fungsionalitas ke dalam batas kesalahan. kebutuhan utama adalah untuk dapat melakukan sesuatu dengan semantik seperti ini:

<MyApp>
    <HandleErrors>
        <ThirdPartyComponent />
    </HandleErrors>
    <HandleErrors>
        <SomeOtherComponent />
    </HandleErrors>
</MyApp>

jika salah satu komponen gagal dirender, kita perlu aplikasi lainnya untuk melanjutkan. itu setara dengan aplikasi desktop kaya-data di mana Anda menyajikan beberapa bilah sisi atau menjalankan beberapa fungsi logika bisnis, yang gagal, tetapi aplikasi tidak mogok dan membuang data di bidang formulir.

dalam sesuatu seperti WPF, penggunaan pemisahan tampilan/model yang ketat mengurangi kekhawatiran ini; praktik terbaik adalah menggunakan MVVM atau MVC atau apa pun dan memiliki penanganan kesalahan di sekitar logika yang dipicu oleh atau yang memperbarui tampilan. namun, pandangan idiomatik blazer terlalu penting dan rawan kesalahan untuk itu masuk akal. sulit untuk menulis file .xaml yang akan menurunkan aplikasi, tetapi dalam .razor itu sepele untuk memiliki pengecualian yang tidak tertangani selama rendering , baik dari pengikatan data ke properti yang didukung ORM atau hanya karena Anda menulis

<strong i="7">@if</strong> (mightBeNull.Value) {
    <br>
}

Bukankah ILogger sudah menjadi tempat yang terpusat?

Seperti @julienGrd, saya memerlukan cara untuk menangkap MsalUiRequiredException secara global sehingga saya dapat mengarahkan pengguna ke login untuk meminta cakupan tambahan. Di MVC ada filter pengecualian tindakan yang menangani ini tetapi Blazor tidak memiliki yang setara.

Mungkin ILogger adalah tempat saya seharusnya melakukan ini entah bagaimana? Jika demikian, rasanya tidak enak. Pengecualian saya adalah yang terkait dengan autentikasi, jadi ini adalah masalah lintas sektoral dan saya perlu cara untuk menghadapinya yang tidak mencemari seluruh aplikasi saya.

@kenchilada Saya tahu rasanya menambahkan penangan pengecualian "global" akan menjadi solusi cepat untuk masalah Anda, tetapi setiap kali Anda menggunakan pendekatan itu, kode Anda benar-benar kehilangan jejak aliran yang sedang berlangsung. Anda tidak memiliki cara untuk mempertahankan status, dan tidak ada cara untuk menyediakan UX yang tidak membuang apa pun yang terjadi saat itu. Secara umum, jauh lebih baik untuk menempatkan try/catch tertentu di dalam UI yang mungkin memicunya sehingga Anda dapat melanjutkan tanpa membuang semua status lokal.

Namun jika Anda benar-benar ingin menangani ini pada tingkat "global" maka ya, ILogger adalah cara Anda dapat melakukannya.

Masalahnya adalah penanganan berbasis try-catch tidak mungkin dilakukan dengan model RenderTreeBuilder. Kamu bisa menulis

<strong i="6">@try</strong>
{
    <p>@{throw new Exception();}</p>
}
catch (Exception e)
{
    <p>An error occurred.</p>
}

..tapi itu tidak akan menampilkan "Terjadi kesalahan.", itu akan menurunkan seluruh rangkaian. Anda bahkan tidak mendapatkan log konsol dan #blazor-error-ui.

@SteveSandersonMS Saya sepenuhnya setuju dengan Anda dalam "teori" tetapi saya dalam konteks tertentu di mana saya tidak tahu bagaimana menanganinya, mungkin Anda akan memiliki beberapa jawaban.

Saya menyinkronkan banyak kode dari aplikasi silverlight yang ada, yang saya lakukan migrasi teknis ke blazor, tetapi tetap menjaga kompatibilitas dan berbagi kode antara kedua aplikasi karena jumlah pekerjaannya sangat besar dan kedua aplikasi harus bekerja berdampingan selama beberapa saat .

jadi masalah saya adalah ViewModel disinkronkan pada layanan wcf panggilan sisi klien seperti ini:
````
public void MyFunction(){
wcfClient.MyFunctionCompleted += MyFunctionCompleted;
wcfClient.Fungsi Saya();
}

private void MyFunctionCompleted(pengirim objek, argumen MyFunctionCompletedArgs){
//hasil ada di sini, dan kemungkinan pengecualian juga
//kita harus menganggap kode ini tidak aman jadi punya cara untuk menangkapnya
}
````

jadi ketika saya memanggil metode model tampilan saya di tampilan blazer saya, tidak ada gunanya melakukan sesuatu seperti ini
private void ButtonClick(){ try{ myViewModel.MyFunction(); } catch(Exception ex){ //i can't catch the exception in the service or happened in the callback } }

Jadi saya tidak tahu bagaimana menangani pengembalian pengecualian oleh layanan, atau pengecualian terjadi langsung di panggilan balik, saya kehilangan kendali.

Terima kasih atas bantuan Anda !

dalam hal ini, Anda sebenarnya dapat menggunakan TaskCompletionSource. katakanlah MyFunctionCompletedArgs berisi pengecualian atau nilai tipe TResult, itu akan menjadi seperti ini:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

lalu di sisi Blazor, tunggu sampai janji selesai:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Ada banyak skenario pemrograman/perangkat lunak.

Kesimpulan saya dari diskusi ini adalah bahwa Microsoft (Setidaknya saat ini) tidak ingin kita menggunakan Blazor untuk aplikasi "besar" atau aplikasi LOB karena mereka mengharapkan kita untuk meletakkan blok coba/tangkap di mana-mana.

Anda mungkin dapat membangun aplikasi "kecil" dengan cara ini. (juga, seperti yang saya sebutkan, ini bukan praktik yang baik)

Tetapi aplikasi LOB dengan banyak kasus penggunaan dan 10-20 (dan bahkan lebih) pengembang dalam satu tim tidak dapat bekerja seperti itu.

Tentu saja ada lebih banyak masalah dengan Blazor saat ini, tetapi masalah ini muncul sekitar 10-15 menit setelah mulai membangun POC.

Hai,

Benar kata. Semoga Microsoft akan memberikan pembaruan untuk bagian akhir tahun ini.

Idealnya, penanganan kesalahan tidak mungkin terjadi di mana-mana dan ketika sirkuit putus, pengembang tidak akan pergi ke mana. Kami adalah pengguna awal Blazor dan merupakan bagian dari migrasi untuk salah satu proyek perusahaan saya.

Ada banyak hal yang perlu dipoles di Blazor.

Terima kasih & Salam,

Ankit Bansal

Game Ilmiah

Dari: Hagay Goshen [email protected]
Dikirim: Selasa, 26 Mei 2020 12:21
Kepada: dotnet/aspnetcore [email protected]
Cc: bansalankit2601 [email protected] ; Komentar [email protected]
Subjek: Re: [dotnet/aspnetcore] [Blazor] Penanganan pengecualian global (#13452)

Ada banyak skenario pemrograman/perangkat lunak.

Kesimpulan saya dari diskusi ini adalah bahwa Microsoft (Setidaknya saat ini) tidak ingin kami menggunakan Blazor untuk aplikasi "besar" atau aplikasi LOB karena mereka mengharapkan kami untuk meletakkan blok coba/tangkap di mana-mana.

Anda mungkin dapat membangun aplikasi "kecil" dengan cara ini. (juga, seperti yang saya sebutkan, ini bukan praktik yang baik)

Tetapi aplikasi LOB dengan banyak kasus penggunaan dan 10-20 (dan bahkan lebih) pengembang dalam satu tim tidak dapat bekerja seperti itu.

Tentu saja ada lebih banyak masalah dengan Blazor saat ini, tetapi masalah ini muncul sekitar 10-15 menit setelah mulai membangun POC.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-633799650 , atau berhenti berlangganan https://github.com/notifications/unsubscribe-auth/ANKYSDATEUMBPN43PYQU2ZDRTM7T3ANCNFSM4IPQWA6 . https://github.com/notifications/beacon/ANKYSDD3JBBDUMUWMZ5NQXDRTM7T3A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEXDQHYQ.gif

Ada banyak skenario pemrograman/perangkat lunak.

Kesimpulan saya dari diskusi ini adalah bahwa Microsoft (Setidaknya saat ini) tidak ingin kami menggunakan Blazor untuk aplikasi "besar" atau aplikasi LOB karena mereka mengharapkan kami untuk meletakkan blok coba/tangkap di mana-mana.

Anda mungkin dapat membangun aplikasi "kecil" dengan cara ini. (juga, seperti yang saya sebutkan, ini bukan praktik yang baik)

Tetapi aplikasi LOB dengan banyak kasus penggunaan dan 10-20 (dan bahkan lebih) pengembang dalam satu tim tidak dapat bekerja seperti itu.

Tentu saja ada lebih banyak masalah dengan Blazor saat ini, tetapi masalah ini muncul sekitar 10-15 menit setelah mulai membangun POC.

Di sinilah kami mendarat juga. Kami menggunakannya untuk antarmuka admin backend tetapi saat ini terlalu baru untuk digunakan untuk aplikasi yang dihadapi pelanggan kami.

@gulbanana terima kasih atas tipnya! Tidak yakin saya akan menjaga kompatibilitas dengan aplikasi silverlight dengan kode semacam ini, tetapi saya harus mencoba (bahkan jika saya lebih suka solusi penanganan pengecualian global)

dalam hal ini, Anda sebenarnya dapat menggunakan TaskCompletionSource. katakanlah MyFunctionCompletedArgs berisi pengecualian atau nilai tipe TResult, itu akan menjadi seperti ini:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

lalu di sisi Blazor, tunggu sampai janji selesai:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Agak bingung di sini... Jika penanganan pengecualian global tidak dapat dilakukan, lalu mengapa ada produk di luar sana
untuk blazer yang mengklaim bahwa "Semua pengecualian yang tidak tertangkap dicatat secara otomatis"?:
https://docs.elmah.io/logging-to-elmah-io-from-blazor/

@rono1 Sekarang Anda dapat menghubungkan ke pipa logging dan mencatat pengecualian -- itu tidak berarti Anda telah "menangani" pengecualian, hanya saja Anda dapat mencatatnya secara global. Saya berterima kasih untuk logging, meskipun!

Kami telah memindahkan masalah ini ke pencapaian Backlog. Ini berarti bahwa itu tidak akan dikerjakan untuk rilis mendatang. Kami akan menilai kembali backlog setelah rilis saat ini dan mempertimbangkan item ini pada saat itu. Untuk mempelajari lebih lanjut tentang proses manajemen masalah kami dan untuk memiliki harapan yang lebih baik mengenai berbagai jenis masalah, Anda dapat membaca Proses Triage kami.

Satu kemungkinan yang kami pertimbangkan untuk masa depan adalah memiliki mekanisme opsional "per component unhandled exception". Jika mekanisme ini diaktifkan, maka framework akan melakukan logika try/catch sendiri di sekitar semua panggilan ke dalam metode siklus hidup komponen, event handler, dan logika rendering. Jika kerangka kerja menangkap pengecualian pada tingkat itu, itu akan menganggap bahwa komponen individu mati (dan mungkin menggantinya di UI dengan semacam komponen "kesalahan") tetapi tidak akan memengaruhi eksekusi rangkaian lainnya.

Apakah menurut Anda pendekatan semacam itu akan memenuhi kebutuhan Anda?

@SteveSandersonMS Apakah ini sedang dipertimbangkan untuk implementasi? Ini akan menghasilkan pengalaman pengguna yang lebih baik dan perangkat lunak yang lebih kuat.

+1 pada ini. Kami benar-benar seharusnya membungkus setiap acara dalam try/catch ? Saya baru saja pergi ke lubang kelinci untuk mencoba mengatasi ini dengan beberapa komponen dasar untuk mengelola status karena betapa menyakitkannya ini.

+1 juga untuk ini. Pendekatan coba/tangkap sebenarnya bukan pilihan untuk solusi yang lebih besar dengan banyak pengembang.

Saya mengatasi ini di aplikasi blazer sisi klien saya dengan menggunakan penyedia logging khusus:
https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Tampaknya agak aneh menggunakan logger sebagai penangan pengecualian global tetapi pada saat ini saya tidak menemukan pendekatan yang lebih bersih seperti sekarang

Tim Blazor pasti perlu melakukan sesuatu tentang ini
permintaan/masalah.

Pada hari Minggu, 4 Okt 2020 pukul 15:24, Markus Reinhardt [email protected]
menulis:

>
>
>

Saya mengatasi ini di aplikasi blazer sisi klien saya dengan menggunakan pencatatan khusus
pemberi:

https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Tampaknya agak aneh menggunakan logger sebagai penangan pengecualian global tetapi pada saya
tidak menemukan pendekatan yang lebih bersih seperti sekarang


Anda menerima ini karena Anda berlangganan utas ini.
Balas email ini secara langsung, lihat di GitHub
https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-703255415 ,
atau berhenti berlangganan
https://github.com/notifications/unsubscribe-auth/AEVARXEEHAOU532C26QCGXLSJBZRRANCNFSM4IPQWA6Q
.

Terima kasih telah menghubungi kami.
Kami memindahkan masalah ini ke pencapaian Next sprint planning untuk evaluasi/pertimbangan di masa mendatang. Kami akan mengevaluasi permintaan tersebut ketika kami merencanakan pekerjaan untuk pencapaian berikutnya. Untuk mempelajari lebih lanjut tentang apa yang diharapkan selanjutnya dan bagaimana masalah ini akan ditangani, Anda dapat membaca lebih lanjut tentang proses triase kami di sini .

Bagi siapa pun yang mencari solusi sisi klien:

function reportError(error) {
  if (DotNet) {
    DotNet.invokeMethodAsync('MyApp.Client', 'NotifyError', error);
  }
}

var exLog = console.error;
console.error = function (msg) {
  exLog.apply(console, arguments);
  reportError(msg);
}

window.addEventListener("unhandledrejection", function (promiseRejectionEvent) {
  reportError(promiseRejectionEvent.reason.message);
});
  public partial class AppLayout
  {
    [JSInvokable("NotifyError")]
    public static void NotifyError(string error)
    {
      //Handle errors
    }
  }

Dukungan peramban

Ini adalah fitur yang sangat penting untuk aplikasi produksi dan saya tidak akan merasa nyaman merilis aplikasi di mana saya tidak dapat mengontrol perilaku aplikasi jika terjadi kesalahan yang tidak tertangani, atau setidaknya dapat mencatatnya dengan andal. Untungnya, saya yakin ada cukup dukungan untuk ini dalam JavaScript yang dapat kami manfaatkan, namun ini adalah celah yang cukup besar untuk membuat saya mempertanyakan apakah teknologi ini benar-benar cukup matang untuk diadopsi dalam aplikasi serius.

Saya harap penangan kesalahan global ini diprioritaskan dalam rilis mendatang.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat