`DeviceData`: Refactor and improve error handling. (#9717)
This PR refactors `DeviceData` node implementation, and improves its
error handling by making it override `SafeLower`. It also improves error
handling of other functions called by the `SafeLower` function.
**Key Changes:**
- Modified `LoweringContext::GetParameter` function to use status for
error propagation
- Created a new `ComputationClient::Data::SafeGetHandle` function that
wraps `GetHandle`, transforming exceptions into status errors
- Created a new `AsComputationClientData` function that converts
`BackendDataPtr` into `ComputationClient::DataPtr`, returning an error
status if the `BackendDataPtr` is not a `ComputationClient::Data`
- **`DeviceData` Refactoring:**
- Factored `DeviceData` constructor body into its own function for
propagating sharding information
- Replaced `stringstream` by `StrCat`
- Replaced `Lower` overried by `SafeLower`