This follows the ld.bfd/gold behavior.
The error check is useful as it turns a common type of ld.so undefined symbol errors into link-time errors:
// a.cc => a.so (not linked with -z defs)
void f(); // f is undefined
void g() { f(); }
// b.cc => executable with a DT_NEEDED entry on a.so
void g();
int main() { g(); }
// ld.so errors when g() is executed (lazy binding) or when the program is started (LD_BIND_NOW)
// symbol lookup error: ... undefined symbol: f