Error handling
-
Use
try/catch
blocks to handle errors that could occur during runtime. Render an error snackbar to the user with a descriptive error message when an error occurs.try { await savePatientData(patient); showSnackbar({ title: t('patientSaved', 'Patient data saved successfully') }); } catch (error) { showSnackbar({ title: t('errorSavingPatient', 'Error saving patient'), kind: 'error', description: error?.message ?? t('unknownError', 'An unknown error occurred'), }); }
-
Don't check the response status of a request to determine whether to show a success snackbar. Instead, always show a success snackbar after a request is successful.
openmrsFetch
will throw an error if the request fails, so you don't need to check the response status to determine whether to show a success or error snackbar.// Don't do this saveVisit(visitPayload).then((response) => { if (response.status === 201) { // Handle the success case } else { // Handle the error case } });
// Instead, do this: saveVisit(visitPayload).then(() => { // Handle the success case }).catch((error) => { // Handle the error case });
Alternatively, you can use
async/await
syntax to handle the success and error cases:try { await saveVisit(visitPayload); // Handle the success case } catch (error) { // Handle the error case }
-
When handling errors in async functions, prefer
async/await
over promise chains for better readability and error handling clarity. For example:// Avoid promise chains savePatientData(patient) .then((response) => { showSnackbar({ kind: 'success', title: t('patientSaved', 'Patient data saved successfully') }); return response; }) .then(processPatientData) .catch((error) => { showSnackbar({ title: t('errorSavingPatient', 'Error saving patient'), kind: 'error', description: error?.message }); }); // Prefer async/await async function handleSavePatient(patient) { try { await savePatientData(patient); showSnackbar({ kind: 'success', title: t('patientSaved', 'Patient data saved successfully') }); } catch (error) { showSnackbar({ title: t('errorSavingPatient', 'Error saving patient'), kind: 'error', description: error?.message }); } }
The
async/await
approach:- Makes the code flow more readable and sequential.
- Simplifies error handling with a single try/catch block.
- Makes it easier to debug since stack traces are more meaningful.
- Allows easier handling of multiple async operations.
Use a
finally
block to execute cleanup code that should run regardless of whether the operation succeeded or failed:async function handleSavePatient(patient) { try { // ... } catch (error) { // Handle the error case } finally { // Do any additional cleanup work closeModal(); } }