Defensive Programming
Status Codes
A small status value can explain why a validation step succeeded or failed.
status code
Returning a status keeps normal error reporting explicit and traceable.
Status Codes
status_codes.cpp
Replay: real traced execution (multi-file project)
#include <iostream>
#include <string>
enum class PasswordStatus {
ok,
empty,
tooShort
};
PasswordStatus checkPassword(const std::string& password) {
if (password.empty()) {
return PasswordStatus::empty;
}
if (password.size() < 6) {
return PasswordStatus::tooShort;
}
return PasswordStatus::ok;
}
std::string labelFor(PasswordStatus status) {
if (status == PasswordStatus::ok) {
return "ok";
}
if (status == PasswordStatus::empty) {
return "empty";
}
return "tooShort";
}
int main() {
std::string password = "safe123";
PasswordStatus status = checkPassword(password);
std::cout << "passwordLength=" << password.size() << std::endl;
std::cout << "status=" << labelFor(status) << std::endl;
return 0;
}
#include <iostream>
#include <string>
enum class PasswordStatus {
ok,
empty,
tooShort
};
PasswordStatus checkPassword(const std::string& password) {
if (password.empty()) {
return PasswordStatus::empty;
}
if (password.size() < 6) {
return PasswordStatus::tooShort;
}
return PasswordStatus::ok;
}
std::string labelFor(PasswordStatus status) {
if (status == PasswordStatus::ok) {
return "ok";
}
if (status == PasswordStatus::empty) {
return "empty";
}
return "tooShort";
}
int main() {
std::string password = "";
PasswordStatus status = checkPassword(password);
std::cout << "passwordLength=" << password.size() << std::endl;
std::cout << "status=" << labelFor(status) << std::endl;
return 0;
}
#include <iostream>
#include <string>
enum class PasswordStatus {
ok,
empty,
tooShort
};
PasswordStatus checkPassword(const std::string& password) {
if (password.empty()) {
return PasswordStatus::empty;
}
if (password.size() < 6) {
return PasswordStatus::tooShort;
}
return PasswordStatus::ok;
}
std::string labelFor(PasswordStatus status) {
if (status == PasswordStatus::ok) {
return "ok";
}
if (status == PasswordStatus::empty) {
return "empty";
}
return "tooShort";
}
int main() {
std::string password = "abc";
PasswordStatus status = checkPassword(password);
std::cout << "passwordLength=" << password.size() << std::endl;
std::cout << "status=" << labelFor(status) << std::endl;
return 0;
}
password ← safe123
30int main() {31 std::string password→ safe123 = "safe123"; //@password="", "abc"3233 PasswordStatus status = checkPassword(passwordsafe123);PasswordStatus checkPassword(const std::string& password)
10PasswordStatus checkPassword(const std::string& passwordsafe123) {11 if (password.empty()) {12 return PasswordStatus::empty;13 }14 if (password.size() < 6) {15 return PasswordStatus::tooShort;16 }17 return PasswordStatus::ok;18}status ← 0
33PasswordStatus status→ 0 = checkPassword(passwordsafe123);3435std::cout << "passwordLength=" << passwordsafe123.size() << std::endl;36std::cout << "status=" << labelFor(status0) << std::endl;37return 0;outputpasswordLength=7std::string labelFor(PasswordStatus status)
20std::string labelFor(PasswordStatus status0) {21 if (status == PasswordStatus::ok) {if (status == PasswordStatus::ok)
20std::string labelFor(PasswordStatus status) {21 if (status0 == PasswordStatus::ok) {22 return "ok";23 }std::cout << "status=" << labelFor(status) << std::endl;
35 std::cout << "passwordLength=" << password.size() << std::endl;36 std::cout << "status=" << labelFor(status0) << std::endl;37 return 0;38}outputstatus=ok
password ← (empty)
30int main() {31 std::string password→ (empty) = "";3233 PasswordStatus status = checkPassword(password(empty));PasswordStatus checkPassword(const std::string& password)
10PasswordStatus checkPassword(const std::string& password(empty)) {11 if (password.empty()) {if (password.empty())
10PasswordStatus checkPassword(const std::string& password) {11 if (password(empty).empty()) {12 return PasswordStatus::empty;13 }status ← 1
33PasswordStatus status→ 1 = checkPassword(password(empty));3435std::cout << "passwordLength=" << password(empty).size() << std::endl;36std::cout << "status=" << labelFor(status1) << std::endl;37return 0;outputpasswordLength=0std::string labelFor(PasswordStatus status)
20std::string labelFor(PasswordStatus status1) {21 if (status == PasswordStatus::ok) {if (status == PasswordStatus::empty)
23}24if (status1 == PasswordStatus::empty) {25 return "empty";26}std::cout << "status=" << labelFor(status) << std::endl;
35 std::cout << "passwordLength=" << password.size() << std::endl;36 std::cout << "status=" << labelFor(status1) << std::endl;37 return 0;38}outputstatus=empty
password ← abc
30int main() {31 std::string password→ abc = "abc";3233 PasswordStatus status = checkPassword(passwordabc);PasswordStatus checkPassword(const std::string& password)
10PasswordStatus checkPassword(const std::string& passwordabc) {11 if (password.empty()) {if (password.size() < 6)
13}14if (passwordabc.size() < 6) {15 return PasswordStatus::tooShort;16}status ← 2
33PasswordStatus status→ 2 = checkPassword(passwordabc);3435std::cout << "passwordLength=" << passwordabc.size() << std::endl;36std::cout << "status=" << labelFor(status2) << std::endl;37return 0;outputpasswordLength=3std::string labelFor(PasswordStatus status)
20std::string labelFor(PasswordStatus status2) {21 if (status == PasswordStatus::ok) {22 return "ok";23 }24 if (status == PasswordStatus::empty) {25 return "empty";26 }27 return "tooShort";28}std::cout << "status=" << labelFor(status) << std::endl;
35 std::cout << "passwordLength=" << password.size() << std::endl;36 std::cout << "status=" << labelFor(status2) << std::endl;37 return 0;38}outputstatus=tooShort