Comment gérer les erreurs (utilisateurs) ?
D’abord, un point sur Git.
Structure de donnée de l’historique Git¶
Indice : je fais de la recherche en ...

Credits: Marco Eidinger
C’est un DAG (Directed Acyclic Graph) où :
- les sommets sont des commits,
- un arc d’un commit
A
vers un commitB
représente l’évolution d’un dépôt de l’étatA
vers l’étatB
, - le graphe “évolue dans une direction” qui correspond au temps donc il est sans cycle dirigé.
Branchement :
- Les branches en Git correspond à des “branches” de ce graphe.
- Des conflits à cause de branches divergentes arrivent quand un même dépôt se trouve dans deux états différents (
A
pointe à la fois versB
etC
). - Des
merge
fusionnent deux branches en une seule (D
etE
pointent tous les deux versF
).
Nous allons apprendre à naviguer ce graphe en TP !
Gestion des erreurs¶
Programmation robuste¶
Robustesse
La robustesse d’un programme est sa capacité de gérer des erreurs et de permettre aux utilisateurs d’identifier les problèmes et de les corriger. La robustesse concerne aussi la conception du programme et non seulement l’écriture des gestionnaires d’erreurs.
Input validation¶
Pour certaines erreurs, il n’est pas nécessaire d’arrêter l’exécution du programme et il suffit de valider l’entrée de l’utilisateur avant de passer à l’étape suivante.
#include <iostream>
#include <limits> // for numeric_limits
#include <stdexcept>
int getPositiveInteger() {
int userInput;
int attempts = 0;
const int maxAttempts = 5;
while (attempts < maxAttempts) {
std::cout << "Enter a positive integer: ";
std::cin >> userInput;
if (std::cin.fail() || userInput <= 0) { // cin.fail() is true if user inputs non-integer value or the value is too large
std::cin.clear(); // cin.clear() resets the state of cin if it was in fail state
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear the buffer until it reaches end of line character '\n'.
attempts++;
std::cout << "Invalid input. Please try again. For example: 1" << std::endl;
std::cout << maxAttempts - attempts << " left." << std::endl;
} else {
return userInput;
}
}
// Explained below
throw std::invalid_argument("Maximum attempts reached.");
}
try, throw, catch¶
Standard exception
Quelques exceptions utiles de la bibliothèque standard de C++:
std::exception
est l’exception de base qui se dérive en :
std::logic_error
:std::invalid_argument
std::out_of_range
std::runtime_error
:std::overflow_error
Consulter C++ exceptions standard pour beaucoup plus de types d’exceptions.
Soyez précis quand vous pouvez et évitez d’utiliser juste std::exception
.
Ne pas gérer les erreurs de développeurs !
Il est crucial de gérer les erreurs d’utilisateur, mais attraper des erreurs imprévues dans le code des développeurs peut compliquer le débogage. C’est pourquoi il est important d’utiliser throw
avec un catch
approprié, afin de ne pas capturer des erreurs inattendues.
null
, c’est nul !
null
, c’est nul !Il faut éviter d’utiliser nullptr
en C++ (null
en Java et C#). Vous allez passer votre temps à vérifier si un objet est nullptr
et cela rend le code illisible.
Exemple:
void registerItemInStore(Item* item, Store store) {
if (item != nullptr) {
ItemRegistry* registry = store.getItemRegistry();
if (registry != nullptr) {
Item* existing = registry->getItem(item->getID());
if (existing->getBillingPeriod().hasRetailOwner()) {
existing->register(item);
}
}
}
}
Est-ce que vous avez remarqué que l’on n’a pas vérifié si existing
est nullptr
?