callback receives err, result