-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: improve fallback to null on empty responses #2285
Merged
ueman
merged 7 commits into
cfug:main
from
knaeckeKami:fix/fused_transformer_null_fallback
Sep 3, 2024
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
f73ff71
fix: improve fallback to null on empty responses
knaeckeKami 79d88f4
fix: improve fallback to null on empty responses
knaeckeKami 9c02075
Update dio/CHANGELOG.md
knaeckeKami 61ad86e
remove duplicated test after merge
knaeckeKami eac00c9
Merge branch 'fix/fused_transformer_null_fallback' of https://github.…
knaeckeKami 0f9dcff
replace compound bitwise assignment with regular assignment
knaeckeKami 1591321
Update CHANGELOG.md
knaeckeKami File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
48 changes: 48 additions & 0 deletions
48
dio/lib/src/transformers/util/transform_empty_to_null.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import 'dart:async'; | ||
import 'dart:typed_data'; | ||
|
||
/// A [StreamTransformer] that replaces an empty stream of Uint8List with a default value | ||
/// - the utf8-encoded string "null". | ||
/// Feeding an empty stream to a JSON decoder will throw an exception, so this transformer | ||
/// is used to prevent that; the JSON decoder will instead return null. | ||
class DefaultNullIfEmptyStreamTransformer | ||
extends StreamTransformerBase<Uint8List, Uint8List> { | ||
const DefaultNullIfEmptyStreamTransformer(); | ||
|
||
@override | ||
Stream<Uint8List> bind(Stream<Uint8List> stream) { | ||
return Stream.eventTransformed( | ||
stream, | ||
(sink) => _DefaultIfEmptyStreamSink(sink), | ||
); | ||
} | ||
} | ||
|
||
class _DefaultIfEmptyStreamSink implements EventSink<Uint8List> { | ||
_DefaultIfEmptyStreamSink(this._outputSink); | ||
|
||
/// Hard-coded constant for replacement value, "null" | ||
static final Uint8List _nullUtf8Value = | ||
Uint8List.fromList(const [110, 117, 108, 108]); | ||
|
||
final EventSink<Uint8List> _outputSink; | ||
bool _hasData = false; | ||
|
||
@override | ||
void add(Uint8List data) { | ||
_hasData = _hasData || data.isNotEmpty; | ||
_outputSink.add(data); | ||
} | ||
|
||
@override | ||
void addError(e, [st]) => _outputSink.addError(e, st); | ||
|
||
@override | ||
void close() { | ||
if (!_hasData) { | ||
_outputSink.add(_nullUtf8Value); | ||
} | ||
|
||
_outputSink.close(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does the value help with?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's for adding the byte sequence for "null" to the response stream, in the case that the response stream is unexpectedly empty.
So we return
null
instead of throwing an exception.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that cause a side effect that user won't understand why their response becomes
"null"
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For clarification: The response won't become the String
"null"
, it would become the valuenull
after the json decoder decodes that byte sequence.It has always been the behavior of Dio to return
null
when theResponseType
is.json
and the response is empty.Only in the recent release with the
FusedTransformer
there is now a corner case that ifResponseType
is.json
andContent-Type
header isapplication/json
andContent-Length
header has a value of > 0 andThat an exception is thrown (instead of the old behavior of returning null).
This is because we currently assume that if the
Content-Length
is>0
, that the response body will not be empty. So the response stream is fed into the json decoder, but the decoder throws on empty streams.This transformation is not applied for other
ResponseType
than.json
.I would also be okay with removing the behavior of returning null on empty responses when the
ResponseType
is.json
but the body is empty completely, and always throw an exception in that case.But that would be a breaking change for sure.
The behavior of the current release, where it mostly returns
null
on empty responses but throws an exception in certain corner cases (mostly responses that are invalid according to the HTTP spec, but still occur in the real world), is not ideal IMO.