The exit status of grep doesn’t necessarily indicate an error ; it indicates success or failure. grep defines success as matching 1 or more lines. Failure includes matching zero lines, or some other error that prevented matching from taking place in the first place.
-q is used when you don’t care about which lines matched, only that some lines matched.
if grep -q foo file.txt; then
echo "file.txt contains foo"
else
echo "file.txt does not contain foo"
fi