sdk
sdk copied to clipboard
[web] [DDC] TypeError: Cannot read properties of undefined (reading 'new')
This tracker is for issues related to:
- Dart native and web compilers
- Dart VM
Upstream: https://github.com/cfug/dio/issues/2282
We've split our Dio adapter with conditional imports. However, writing the caller in a specific way does not reference the correct constructor as I can tell.
Consider the example, running this on Flutter Web environment will unexpectedly throw TypeError: Cannot read properties of undefined (reading 'new'):
main.dart
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'adapter.dart';
void main() {
try {
final adapter = makeHttpClientAdapter();
print(adapter);
} on Object catch (error) {
print(error);
}
runApp(const MyApp());
}
adapter.dart
import 'package:dio/dio.dart';
import 'client_adapter_io.dart'
if (dart.library.js_interop) 'client_adapter_web.dart' as adapter;
HttpClientAdapter makeHttpClientAdapter() => adapter.makeHttpClientAdapter();
adapter_io.dart
import 'package:dio/dio.dart';
import 'package:dio/io.dart';
HttpClientAdapter makeHttpClientAdapter() {
return IOHttpClientAdapter();
}
adapter_web.dart
import 'package:dio/browser.dart';
import 'package:dio/dio.dart';
HttpClientAdapter makeHttpClientAdapter() {
return BrowserHttpClientAdapter()..withCredentials = true;
}
Workaround
HttpClientAdapter makeHttpClientAdapter() {
final adapter = HttpClientAdapter() as BrowserHttpClientAdapter;
adapter.withCredentials = true;
return adapter;
}
Summary: The issue is a TypeError thrown when using conditional imports with Dio on Flutter Web. The error occurs because the correct constructor for the HttpClientAdapter is not being referenced due to the way the caller is written.
@Rexios80 Do you have any clues what is going on here? 🤔
What dart/flutter version? There might be some fixes that still aren't merged into stable.
@Rexios80 im faced this:
[✓] Flutter (Channel stable, 3.22.2, on macOS 14.5 23F79 darwin-arm64, locale en-RU)
[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 15.4)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2023.2)
[✓] VS Code (version 1.92.2)
[✓] Connected device (5 available)
[✓] Network resources
Can you reproduce on flutter master?
This also happens on master 3.24.0-1.0.pre.606
Is it the cascade that's causing the issue?
You say this is a workaround:
HttpClientAdapter makeHttpClientAdapter() {
final adapter = HttpClientAdapter() as BrowserHttpClientAdapter;
adapter.withCredentials = true;
return adapter;
}
What about this fixes the issue if it's not removing the cascade? Is it the cast?
You say this is a workaround:
HttpClientAdapter makeHttpClientAdapter() { final adapter = HttpClientAdapter() as BrowserHttpClientAdapter; adapter.withCredentials = true; return adapter; }What about this fixes the issue if it's not removing the cascade? Is it the cast?
Yes, creating the adapter like this and force cast it does work, it's not about the cascade. The workaround is to help people to achieve their goal.
Which of the web environments are you experiencing this issue?
- Production JavaScript (dart2js compiler)
- Production WASM (dart2wasm compiler)
- Development (DDC compiler)
Which of the web environments are you experiencing this issue?
- Development (DDC compiler)
The DDC compiler. The built Web application does not run into the issue.
@nshahan - I recall we've seen an error with this message before long ago, but we didn't have a repro at hand. Maybe they are related? (see https://github.com/dart-lang/sdk/issues/50380)
I actually have this error in one of my projects now. Not sure how it took me this long to notice. The workaround provided by @AlexV525 does fix the issue.
This is getting worse according to https://github.com/cfug/dio/issues/2282#issuecomment-2567611491
@nshahan @sigmundch Would you mind taking further investigations?
I'm getting this error using:
Flutter 3.29.0 • channel stable • https://github.com/flutter/flutter.git Framework • revision 35c388afb5 (4 days ago) • 2025-02-10 12:48:41 -0800 Engine • revision f73bfc4522 Tools • Dart 3.7.0 • DevTools 2.42.2
I'm not even using conditional imports or anything. Simply trying to use BrowserHttpClientAdapter() at all throws this error.
I have a fix in progress but to summarize the issue:
package:dio has a dependency on package:dio_web_adapter. Both packages include a file called package:<pkg_name>/browser.dart. package:dio/browser.dart is the library that contains BrowserHttpClientAdapter.
DDC compiles libraries modularly but it can sometimes combine libraries from different packages into the same JS module. In this case both package:dio_web_adapter/browser.dart and package:dio/browser.dart are getting compiled into the same JS module. DDC then tries to create an import/export nickname for each library in the module but gives both the same nickname. So due to this bug when adapter_web.dart imports package:dio/browser.dart, it ends up importing package:dio_web_adapter/browser.dart instead. This is why BrowserHttpClientAdapter seems to be missing.
The workaround to use HttpClientAdapter() instead calls a constructor from a different library, one that doesn't have a naming collision so we can successfully access it from adapter_web.dart. It then calls through to the BrowserHttpClientAdapter constructor from within the same module. Since the call is within the same JS module, the import nickname doesn't matter and so the code for HttpClientAdapter is successfully able to call BrowserHttpClientAdapter().
A quick update here. The fix has landed in the Dart SDK and is rolled into the Flutter SDK master channel. Please feel free to try it out on the master channel.
We're considering the fix medium to high risk given it changes how DDC imports and exports libraries. We want to give the change a chance to be tested in earlier channels before it gets into stable.
Given this package:dio example is the only example we've heard of triggering this issue and given there is a simple workaround, we've decided not to cherrypick the fix. We ask that anyone hitting this issue use the workaround above.
In production builds the code produced by the workaround should be nearly identical to that produced by the broken pattern. So there should be no performance implications to the workaround.
@AlexV525 Thank you for filing this and providing a workaround.
I can confirm the issue was resolved with that rolled commit. @biggs0125 Thanks for the fix!