initResult method
Unlike init (which never throws — a fetch failure just falls back to defaults, see the class doc), this DOES surface a failed remote fetch as an SdkFailure — a caller that wants to know "did boot actually succeed" shouldn't have to separately check source to notice the difference between "remote merged" and "silently fell back". init itself is unaffected: it still never throws and still sets source exactly as before — this only changes what initResult REPORTS about that outcome.
Implementation
Future<SdkResult<void>> initResult() async {
try {
await init();
} catch (error, stack) {
// init() is documented never-throws, but this stays defensive in
// case a future edit there breaks that contract — still reported as
// the same kind of failure a fetch failure would be.
return SdkFailure(
kind: SdkErrorKind.network,
message: 'Remote configuration unavailable',
retryable: true,
cause: error,
stackTrace: stack,
);
}
if (_source == RemoteConfigSource.remoteFailed) {
return const SdkFailure(
kind: SdkErrorKind.network,
message: 'Remote configuration fetch failed, using fallback config',
retryable: true,
);
}
if (_schemaViolations.isNotEmpty) {
// ENH-84: caught centrally here instead of at whatever call site
// eventually reads the wrong-typed key — lists every violating key
// by name so a misconfigured CMS/server value is diagnosable from
// this single result, not from a stack trace deep inside game logic.
return SdkFailure(
kind: SdkErrorKind.validation,
message:
'Remote configuration failed schema validation: '
'${_schemaViolations.join('; ')}',
retryable: false,
);
}
return const SdkSuccess(null);
}