Bagikan melalui


Pemrosesan Pengecualian

Ketika program dijalankan, sejumlah kondisi abnormal dan kesalahan yang disebut "pengecualian" dapat terjadi. Ini mungkin termasuk kehabisan memori, kesalahan alokasi sumber daya, dan kegagalan untuk menemukan file.

Pustaka Kelas Microsoft Foundation menggunakan skema penanganan pengecualian yang dimodelkan dengan cermat setelah yang diusulkan oleh komite standar ANSI untuk C++. Handler pengecualian harus disiapkan sebelum memanggil fungsi yang mungkin mengalami situasi abnormal. Jika fungsi mengalami kondisi abnormal, fungsi akan melemparkan pengecualian dan kontrol diteruskan ke handler pengecualian.

Beberapa makro yang disertakan dengan Microsoft Foundation Class Library akan menyiapkan handler pengecualian. Sejumlah fungsi global lainnya membantu melemparkan pengecualian khusus dan menghentikan program, jika perlu. Makro dan fungsi global ini termasuk dalam kategori berikut:

  • Makro pengecualian, yang menyusun handler pengecualian Anda.

  • Fungsi pelemparan pengecualian), yang menghasilkan pengecualian dari jenis tertentu.

  • Fungsi penghentian, yang menyebabkan penghentian program.

Untuk contoh dan detail selengkapnya, lihat artikel Pengecualian.

Makro Pengecualian

Nama Deskripsi
COBA Menunjuk blok kode untuk pemrosesan pengecualian.
MENANGKAP Menunjuk blok kode untuk menangkap pengecualian dari blok TRY sebelumnya.
CATCH_ALL Menunjuk blok kode untuk menangkap semua pengecualian dari blok TRY sebelumnya.
AND_CATCH Menunjuk blok kode untuk menangkap jenis pengecualian tambahan dari blok TRY sebelumnya.
AND_CATCH_ALL Menunjuk blok kode untuk menangkap semua jenis pengecualian tambahan lainnya yang dilemparkan dalam blok TRY sebelumnya.
END_CATCH Mengakhiri blok kode CATCH atau AND_CATCH terakhir.
END_CATCH_ALL Mengakhiri blok kode CATCH_ALL terakhir.
THROW Melemparkan pengecualian yang ditentukan.
THROW_LAST Melemparkan pengecualian yang saat ini ditangani ke handler luar berikutnya.

Fungsi Pembuangan Pengecualian

Nama Deskripsi
AfxThrowArchiveException Melempar pengecualian arsip.
AfxThrowFileException Melempar pengecualian file.
AfxThrowInvalidArgException Melempar pengecualian argumen yang tidak valid.
AfxThrowMemoryException Melempar pengecualian memori.
AfxThrowNotSupportedException Melempar pengecualian yang tidak didukung.
AfxThrowResourceException Melempar pengecualian sumber daya Windows yang tidak ditemukan.
AfxThrowUserException Melemparkan pengecualian dalam tindakan program yang dimulai pengguna.

MFC menyediakan dua fungsi pelemparan pengecualian khusus untuk pengecualian OLE:

Fungsi Pengecualian OLE

Nama Deskripsi
AfxThrowOleDispatchException Melempar pengecualian dalam fungsi otomatisasi OLE.
AfxThrowOleException Melempar pengecualian OLE.

Untuk mendukung pengecualian database, kelas database menyediakan dua kelas pengecualian, CDBException dan CDaoException, dan fungsi global untuk mendukung jenis pengecualian:

Fungsi Pengecualian DAO

Nama Deskripsi
AfxThrowDAOException Melempar CDaoException dari kode Anda sendiri.
AfxThrowDBException Melempar CDBException dari kode Anda sendiri.

MFC menyediakan fungsi penghentian berikut:

Fungsi Penghentian

Nama Deskripsi
AfxAbort Dipanggil untuk mengakhiri aplikasi ketika terjadi kesalahan fatal.

TRY

Menyiapkan blok TRY.

TRY

Keterangan

Blok TRY mengidentifikasi blok kode yang mungkin melempar pengecualian. Pengecualian tersebut ditangani di blok CATCH dan AND_CATCH berikut. Rekursi diperbolehkan: pengecualian dapat diteruskan ke blok TRY luar, baik dengan mengabaikannya atau dengan menggunakan makro THROW_LAST. Akhiri blok TRY dengan makro END_CATCH atau END_CATCH_ALL.

Untuk informasi selengkapnya, lihat artikel Pengecualian.

Contoh

Lihat contoh untuk CATCH.

Persyaratan

Header: afx.h

MENANGKAP

Mendefinisikan blok kode yang menangkap jenis pengecualian pertama yang dilemparkan di blok TRY sebelumnya.

CATCH(exception_class, exception_object_pointer_name)

Parameter

exception_class
Menentukan jenis pengecualian yang akan diuji. Untuk daftar kelas pengecualian standar, lihat kelas CException.

exception_object_pointer_name
Menentukan nama untuk penunjuk objek pengecualian yang akan dibuat oleh makro. Anda dapat menggunakan nama penunjuk untuk mengakses objek pengecualian dalam blok CATCH . Variabel ini dideklarasikan untuk Anda.

Keterangan

Kode pemrosesan pengecualian dapat menginterogasi objek pengecualian, jika sesuai, untuk mendapatkan informasi selengkapnya tentang penyebab spesifik pengecualian. Panggil makro THROW_LAST untuk mengalihkan pemrosesan ke bingkai pengecualian luar berikutnya. Akhiri blok TRY dengan makro END_CATCH.

Jika exception_class adalah kelas CException, maka semua jenis pengecualian akan ditangkap. Anda dapat menggunakan fungsi anggota CObject::IsKindOf untuk menentukan pengecualian spesifik mana yang dilemparkan. Cara yang lebih baik untuk menangkap beberapa jenis pengecualian adalah dengan menggunakan pernyataan AND_CATCH berurutan, masing-masing dengan jenis pengecualian yang berbeda.

Penunjuk objek pengecualian dibuat oleh makro. Anda tidak perlu menyatakannya sendiri.

Catatan

Blok CATCH didefinisikan sebagai cakupan C++ yang digambarkan oleh kurung kurawal. Jika Anda mendeklarasikan variabel dalam cakupan ini, variabel hanya dapat diakses dalam cakupan tersebut. Ini juga berlaku untuk exception_object_pointer_name.

Untuk informasi selengkapnya tentang pengecualian dan makro CATCH, lihat artikel Pengecualian.

Contoh

CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
TRY
{
   pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
      CFile::modeRead | CFile::shareDenyNone);
   ULONGLONG dwLength = pFile->GetLength();
   CString str;
   str.Format(_T("Your SYSTEM.INI file is %I64u bytes long.") , dwLength);
   AfxMessageBox(str);
}
CATCH(CFileException, pEx)
{
   // Simply show an error message to the user.
   pEx->ReportError();
}
AND_CATCH(CMemoryException, pEx)
{
   // We can't recover from this memory exception, so we'll
   // just terminate the app without any cleanup. Normally, 
   // an application should do everything it possibly can to
   // clean up properly and not call AfxAbort().
   AfxAbort();
}
END_CATCH
// If an exception occurs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our cleanup code needs to test for NULL.
if (pFile != NULL)
{
   pFile->Close();
   delete pFile;
}

CATCH_ALL

Mendefinisikan blok kode yang menangkap semua jenis pengecualian yang dilemparkan dalam blok TRY sebelumnya.

CATCH_ALL(exception_object_pointer_name)

Parameter

exception_object_pointer_name
Menentukan nama untuk penunjuk objek pengecualian yang akan dibuat oleh makro. Anda dapat menggunakan nama penunjuk untuk mengakses objek pengecualian dalam CATCH_ALL blok. Variabel ini dideklarasikan untuk Anda.

Keterangan

Kode pemrosesan pengecualian dapat menginterogasi objek pengecualian, jika sesuai, untuk mendapatkan informasi selengkapnya tentang penyebab spesifik pengecualian. Panggil THROW_LAST makro untuk mengalihkan pemrosesan ke bingkai pengecualian luar berikutnya. Jika Anda menggunakan CATCH_ALL, akhiri blok TRY dengan makro END_CATCH_ALL.

Catatan

Blok CATCH_ALL didefinisikan sebagai cakupan C++ yang digambarkan oleh kurung kurawal. Jika Anda mendeklarasikan variabel dalam cakupan ini, variabel hanya dapat diakses dalam cakupan tersebut.

Untuk informasi selengkapnya tentang pengecualian, lihat artikel Pengecualian.

Contoh

Lihat contoh untuk CFile::Abort.

Persyaratan

Header afx.h

AND_CATCH

Menentukan blok kode untuk menangkap jenis pengecualian tambahan yang dilemparkan dalam blok TRY sebelumnya.

AND_CATCH(exception_class, exception_object_pointer_name)

Parameter

exception_class
Menentukan jenis pengecualian yang akan diuji. Untuk daftar kelas pengecualian standar, lihat kelas CException.

exception_object_pointer_name
Nama untuk penunjuk objek pengecualian yang akan dibuat oleh makro. Anda dapat menggunakan nama penunjuk untuk mengakses objek pengecualian dalam blok AND_CATCH . Variabel ini dideklarasikan untuk Anda.

Keterangan

Gunakan makro CATCH untuk menangkap satu jenis pengecualian, lalu makro AND_CATCH untuk menangkap setiap jenis berikutnya. Akhiri blok TRY dengan makro END_CATCH.

Kode pemrosesan pengecualian dapat menginterogasi objek pengecualian, jika sesuai, untuk mendapatkan informasi selengkapnya tentang penyebab spesifik pengecualian. Panggil makro THROW_LAST dalam blok AND_CATCH untuk mengalihkan pemrosesan ke bingkai pengecualian luar berikutnya. AND_CATCH menandai akhir blok CATCH atau AND_CATCH sebelumnya.

Catatan

Blok AND_CATCH didefinisikan sebagai cakupan C++ (digambarkan oleh kurung kurawal). Jika Anda mendeklarasikan variabel dalam cakupan ini, ingatlah bahwa variabel tersebut hanya dapat diakses dalam cakupan tersebut. Ini juga berlaku untuk variabel exception_object_pointer_name .

Contoh

Lihat contoh untuk CATCH.

Persyaratan

Header afx.h

AND_CATCH_ALL

Menentukan blok kode untuk menangkap jenis pengecualian tambahan yang dilemparkan dalam blok TRY sebelumnya.

AND_CATCH_ALL(exception_object_pointer_name)

Parameter

exception_object_pointer_name
Nama untuk penunjuk objek pengecualian yang akan dibuat oleh makro. Anda dapat menggunakan nama penunjuk untuk mengakses objek pengecualian dalam blok AND_CATCH_ALL . Variabel ini dideklarasikan untuk Anda.

Keterangan

Gunakan makro CATCH untuk menangkap satu jenis pengecualian, lalu makro AND_CATCH_ALL untuk menangkap semua jenis berikutnya. Jika Anda menggunakan AND_CATCH_ALL, akhiri blok TRY dengan makro END_CATCH_ALL.

Kode pemrosesan pengecualian dapat menginterogasi objek pengecualian, jika sesuai, untuk mendapatkan informasi selengkapnya tentang penyebab spesifik pengecualian. Panggil makro THROW_LAST dalam blok AND_CATCH_ALL untuk mengalihkan pemrosesan ke bingkai pengecualian luar berikutnya. AND_CATCH_ALL menandai akhir blok CATCH atau AND_CATCH_ALL sebelumnya.

Catatan

Blok AND_CATCH_ALL didefinisikan sebagai cakupan C++ (digambarkan oleh kurung kurawal). Jika Anda mendeklarasikan variabel dalam cakupan ini, ingatlah bahwa variabel tersebut hanya dapat diakses dalam cakupan tersebut.

Persyaratan

Header afx.h

END_CATCH

Menandai akhir blok CATCH atau AND_CATCH terakhir.

END_CATCH

Keterangan

Untuk informasi selengkapnya tentang makro END_CATCH, lihat artikel Pengecualian.

Persyaratan

Header afx.h

END_CATCH_ALL

Menandai akhir blok CATCH_ALL88 atau AND_CATCH_ALL terakhir.

END_CATCH_ALL

Persyaratan

Header afx.h

LEMPAR (MFC)

Melemparkan pengecualian yang ditentukan.

THROW(exception_object_pointer)

Parameter

exception_object_pointer
Menunjuk ke objek pengecualian yang berasal dari CException.

Keterangan

THROW mengganggu eksekusi program, meneruskan kontrol ke blok CATCH terkait dalam program Anda. Jika Anda belum menyediakan blok CATCH , maka kontrol diteruskan ke modul Microsoft Foundation Class Library yang mencetak pesan kesalahan dan keluar.

Untuk informasi selengkapnya, lihat artikel Pengecualian.

Persyaratan

Header afx.h

THROW_LAST

Melemparkan pengecualian kembali ke blok CATCH luar berikutnya.

THROW_LAST()

Keterangan

Makro ini memungkinkan Anda untuk melemparkan pengecualian yang dibuat secara lokal. Jika Anda mencoba melemparkan pengecualian yang baru saja Anda tangkap, biasanya akan keluar dari cakupan dan dihapus. Dengan THROW_LAST, pengecualian diteruskan dengan benar ke handler CATCH berikutnya.

Untuk informasi selengkapnya, lihat artikel Pengecualian.

Contoh

Lihat contoh untuk CFile::Abort.

Persyaratan

Header afx.h

AfxThrowArchiveException

Melempar pengecualian arsip.

void  AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);

Parameter

sebab
Menentukan bilangan bulat yang menunjukkan alasan pengecualian. Untuk daftar nilai yang mungkin, lihat CArchiveException::m_cause.

lpszArchiveName
Menunjuk ke string yang berisi nama CArchive objek yang menyebabkan pengecualian (jika tersedia).

Persyaratan

Header afx.h

AfxThrowFileException

Melempar pengecualian file.

void AfxThrowFileException(
    int cause,
    LONG lOsError = -1,
    LPCTSTR lpszFileName = NULL);

Parameter

sebab
Menentukan bilangan bulat yang menunjukkan alasan pengecualian. Untuk daftar nilai yang mungkin, lihat CFileException::m_cause.

lOsError
Berisi nomor kesalahan sistem operasi (jika tersedia) yang menyatakan alasan pengecualian. Lihat manual sistem operasi Anda untuk daftar kode kesalahan.

lpszFileName
Menunjuk ke string yang berisi nama file yang menyebabkan pengecualian (jika tersedia).

Keterangan

Anda bertanggung jawab untuk menentukan penyebabnya berdasarkan kode kesalahan sistem operasi.

Persyaratan

Header afx.h

AfxThrowInvalidArgException

Melempar pengecualian argumen yang tidak valid.

Sintaks

void AfxThrowInvalidArgException( );

Keterangan

Fungsi ini dipanggil ketika argumen yang tidak valid digunakan.

Persyaratan

Header: afx.h

AfxThrowMemoryException

Melempar pengecualian memori.

void AfxThrowMemoryException();

Keterangan

Panggil fungsi ini jika panggilan ke alokator memori sistem yang mendasar (seperti malloc dan fungsi Windows GlobalAlloc ) gagal. Anda tidak perlu menyebutnya new karena new akan melemparkan pengecualian memori secara otomatis jika alokasi memori gagal.

Persyaratan

Header afx.h

AfxThrowNotSupportedException

Memberikan pengecualian yang merupakan hasil dari permintaan untuk fitur yang tidak didukung.

void AfxThrowNotSupportedException();

Persyaratan

Header afx.h

AfxThrowResourceException

Melempar pengecualian sumber daya.

void  AfxThrowResourceException();

Keterangan

Fungsi ini biasanya dipanggil ketika sumber daya Windows tidak dapat dimuat.

Persyaratan

Header afx.h

AfxThrowUserException

Melempar pengecualian untuk menghentikan operasi pengguna akhir.

void AfxThrowUserException();

Keterangan

Fungsi ini biasanya dipanggil segera setelah AfxMessageBox melaporkan kesalahan kepada pengguna.

Persyaratan

Header afx.h

AfxThrowOleDispatchException

Gunakan fungsi ini untuk melemparkan pengecualian dalam fungsi otomatisasi OLE.

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode ,
    LPCSTR lpszDescription,
    UINT nHelpID = 0);

void AFXAPI AfxThrowOleDispatchException(
    WORD wCode,
    UINT nDescriptionID,
    UINT nHelpID = -1);

Parameter

wCode
Kode kesalahan khusus untuk aplikasi Anda.

lpszDescription
Deskripsi verbal tentang kesalahan.

nDescriptionID
ID sumber daya untuk deskripsi kesalahan verbal.

nHelpID
Konteks bantuan untuk bantuan aplikasi Anda (. File HLP).

Keterangan

Informasi yang diberikan untuk fungsi ini dapat ditampilkan oleh aplikasi mengemudi (Microsoft Visual Basic atau aplikasi klien otomatisasi OLE lainnya).

Contoh

// Sort is method of automation class CStrArrayDoc
long CStrArrayDoc::Sort(VARIANT* vArray)
{
   USES_CONVERSION;

   // Type check VARIANT parameter. It should contain a BSTR array
   // passed by reference. The array must be passed by reference; it is
   // an in-out-parameter.

   // throwing COleDispatchException allows the EXCEPINFO structure of 
   // IDispatch::Invoke() to set
   if (V_VT(vArray) != (VT_ARRAY | VT_BSTR))
      AfxThrowOleDispatchException(1001,
         _T("Type Mismatch in Parameter. Pass a string array by reference"));

   // ...
   // ...

   return 0;
}

Persyaratan

Header afx.h

AfxThrowOleException

Membuat objek jenis COleException dan melemparkan pengecualian.

void AFXAPI AfxThrowOleException(SCODE sc);
void AFXAPI AfxThrowOleException(HRESULT hr);

Parameter

Sc
Kode status OLE yang menunjukkan alasan pengecualian.

Hr
Tangani ke kode hasil yang menunjukkan alasan pengecualian.

Keterangan

Versi yang mengambil HRESULT sebagai argumen mengonversi kode hasil tersebut menjadi SCODE yang sesuai. Untuk informasi selengkapnya tentang HRESULT dan SCODE, lihat Struktur Kode Kesalahan COM di Windows SDK.

Persyaratan

Header afxdao.h

AfxThrowDaoException

Panggil fungsi ini untuk melemparkan pengecualian jenis CDaoException dari kode Anda sendiri.

void AFXAPI AfxThrowDaoException(
    int nAfxDaoError = NO_AFX_DAO_ERROR,
    SCODE scode = S_OK);

Parameter

nAfxDaoError
Nilai bilangan bulat yang mewakili kode kesalahan yang diperluas DAO, yang dapat menjadi salah satu nilai yang tercantum di bawah CDaoException::m_nAfxDaoError.

scode
Kode kesalahan OLE dari DAO, jenis SCODE. Untuk informasi, lihat CDaoException::m_scode.

Keterangan

Kerangka kerja juga memanggil AfxThrowDaoException. Dalam panggilan, Anda dapat meneruskan salah satu parameter atau keduanya. Misalnya, jika Anda ingin memunculkan salah satu kesalahan yang ditentukan dalam CDaoException::nAfxDaoError tetapi Anda tidak peduli dengan parameter scode , berikan kode yang valid dalam parameter nAfxDaoError dan terima nilai default untuk scode.

Untuk informasi tentang pengecualian yang terkait dengan kelas MFC DAO, lihat kelas CDaoException dalam buku ini dan artikel Pengecualian: Pengecualian Database.

Persyaratan

Header afxdb.h

AfxThrowDBException

Panggil fungsi ini untuk melemparkan pengecualian jenis CDBException dari kode Anda sendiri.

void AfxThrowDBException(
    RETCODE nRetCode,
    CDatabase* pdb,
    HSTMT hstmt);

Parameter

nRetCode
Nilai jenis RETCODE, menentukan jenis kesalahan yang menyebabkan pengecualian dilemparkan.

pdb
Penunjuk ke CDatabase objek yang mewakili koneksi sumber data yang terkait dengan pengecualian.

hstmt
Handel ODBC HSTMT yang menentukan handel pernyataan yang terkait dengan pengecualian.

Keterangan

Kerangka kerja memanggil AfxThrowDBException ketika menerima ODBC RETCODE dari panggilan ke fungsi ODBC API dan menafsirkan RETCODE sebagai kondisi yang luar biasa daripada kesalahan yang dapat diharapkan. Misalnya, operasi akses data mungkin gagal karena kesalahan baca disk.

Untuk informasi tentang nilai RETCODE yang ditentukan oleh ODBC, lihat Bab 8, "Mengambil Status dan Informasi Kesalahan," di Windows SDK. Untuk informasi tentang ekstensi MFC ke kode ini, lihat kelas CDBException.

Persyaratan

Header afx.h

AfxAbort

Fungsi penghentian default yang disediakan oleh MFC.

void  AfxAbort();

Keterangan

AfxAbort dipanggil secara internal oleh fungsi anggota MFC ketika ada kesalahan fatal, seperti pengecualian yang tidak tertangkap yang tidak dapat ditangani. Anda dapat memanggil AfxAbort dalam kasus yang jarang terjadi ketika Anda mengalami kesalahan besar yang tidak dapat Anda pulihkan.

Contoh

Lihat contoh untuk CATCH.

Persyaratan

Header afx.h

Lihat juga

Makro dan Global
Kelas CException
Kelas CInvalidArgException