Skip to content

Commit 7d7e7f9

Browse files
authored
Fix --log-file option so it doesn't crash the server. (#207)
1 parent 2676dec commit 7d7e7f9

File tree

6 files changed

+60
-48
lines changed

6 files changed

+60
-48
lines changed

.vscode/launch.json

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
11
{
2-
// Use IntelliSense to learn about possible attributes.
3-
// Hover to view descriptions of existing attributes.
4-
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5-
"version": "0.2.0",
6-
"configurations": [
7-
{
8-
"name": "counter_app",
9-
"cwd": "pkgs/dart_tooling_mcp_server/test_fixtures/counter_app",
10-
"request": "launch",
11-
"type": "dart"
12-
},
13-
{
14-
"name": "counter_app (profile mode)",
15-
"cwd": "pkgs/dart_tooling_mcp_server/test_fixtures/counter_app",
16-
"request": "launch",
17-
"type": "dart",
18-
"flutterMode": "profile"
19-
},
20-
{
21-
"name": "counter_app (release mode)",
22-
"cwd": "pkgs/dart_tooling_mcp_server/test_fixtures/counter_app",
23-
"request": "launch",
24-
"type": "dart",
25-
"flutterMode": "release"
26-
}
27-
]
2+
"version": "0.2.0",
3+
"configurations": [
4+
{
5+
"name": "test_mcp",
6+
"program": "pkgs/dart_mcp_server/bin/main.dart",
7+
"cwd": "${workspaceFolder}",
8+
"args": ["--log-file", "pkgs/dart_mcp_server/log.txt"],
9+
"request": "launch",
10+
"type": "dart"
11+
},
12+
{
13+
"name": "counter_app",
14+
"cwd": "pkgs/dart_tooling_mcp_server/test_fixtures/counter_app",
15+
"request": "launch",
16+
"type": "dart"
17+
},
18+
{
19+
"name": "counter_app (profile mode)",
20+
"cwd": "pkgs/dart_tooling_mcp_server/test_fixtures/counter_app",
21+
"request": "launch",
22+
"type": "dart",
23+
"flutterMode": "profile"
24+
},
25+
{
26+
"name": "counter_app (release mode)",
27+
"cwd": "pkgs/dart_tooling_mcp_server/test_fixtures/counter_app",
28+
"request": "launch",
29+
"type": "dart",
30+
"flutterMode": "release"
31+
}
32+
]
2833
}

pkgs/dart_mcp/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
and stdout streams instead of starting processes itself. This enables custom
2121
process spawning (such as using package:process), and also enables the client
2222
to run in browser environments.
23+
- Fixed a problem where specifying `--log-file` would cause the server to stop
24+
working.
2325

2426
## 0.2.2
2527

pkgs/dart_mcp/lib/src/api/initialization.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ extension type InitializeRequest._fromMap(Map<String, Object?> _value)
2828
///
2929
/// May be `null` if the version is not recognized.
3030
ProtocolVersion? get protocolVersion =>
31-
ProtocolVersion.tryParse(_value['protocolVersion'] as String);
31+
ProtocolVersion.tryParse(_value['protocolVersion'] as String? ?? '');
3232

3333
ClientCapabilities get capabilities {
3434
final capabilities = _value['capabilities'] as ClientCapabilities?;

pkgs/dart_mcp_server/lib/src/mixins/analyzer.dart

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ base mixin DartAnalyzerSupport
2424
on ToolsSupport, LoggingSupport, RootsTrackingSupport
2525
implements SdkSupport {
2626
/// The LSP server connection for the analysis server.
27-
late final Peer _lspConnection;
27+
Peer? _lspConnection;
2828

2929
/// The actual process for the LSP server.
30-
late final Process _lspServer;
30+
Process? _lspServer;
3131

3232
/// The current diagnostics for a given file.
3333
Map<Uri, List<lsp.Diagnostic>> diagnostics = {};
@@ -91,7 +91,7 @@ base mixin DartAnalyzerSupport
9191
///
9292
/// On failure, returns a reason for the failure.
9393
Future<String?> _initializeAnalyzerLspServer() async {
94-
_lspServer = await Process.start(sdk.dartExecutablePath, [
94+
final lspServer = await Process.start(sdk.dartExecutablePath, [
9595
'language-server',
9696
// Required even though it is documented as the default.
9797
// https://github.com/dart-lang/sdk/issues/60574
@@ -101,16 +101,17 @@ base mixin DartAnalyzerSupport
101101
// '--protocol-traffic-log',
102102
// 'language-server-protocol.log',
103103
]);
104-
_lspServer.stderr
104+
_lspServer = lspServer;
105+
lspServer.stderr
105106
.transform(utf8.decoder)
106107
.transform(const LineSplitter())
107108
.listen((line) async {
108109
await initialized;
109110
log(LoggingLevel.warning, line, logger: 'DartLanguageServer');
110111
});
111112

112-
_lspConnection =
113-
Peer(lspChannel(_lspServer.stdout, _lspServer.stdin))
113+
final lspConnection =
114+
Peer(lspChannel(lspServer.stdout, lspServer.stdin))
114115
..registerMethod(
115116
lsp.Method.textDocument_publishDiagnostics.toString(),
116117
_handleDiagnostics,
@@ -122,16 +123,17 @@ base mixin DartAnalyzerSupport
122123
() => 'Unhandled LSP message: ${params.method} - ${params.asMap}',
123124
);
124125
});
126+
_lspConnection = lspConnection;
125127

126-
unawaited(_lspConnection.listen());
128+
unawaited(lspConnection.listen());
127129

128130
log(LoggingLevel.debug, 'Connecting to analyzer lsp server');
129131
lsp.InitializeResult? initializeResult;
130132
String? error;
131133
try {
132134
// Initialize with the server.
133135
initializeResult = lsp.InitializeResult.fromJson(
134-
(await _lspConnection.sendRequest(
136+
(await lspConnection.sendRequest(
135137
lsp.Method.initialize.toString(),
136138
lsp.InitializeParams(
137139
capabilities: lsp.ClientCapabilities(
@@ -221,10 +223,10 @@ base mixin DartAnalyzerSupport
221223
}
222224

223225
if (error != null) {
224-
_lspServer.kill();
225-
await _lspConnection.close();
226+
lspServer.kill();
227+
await lspConnection.close();
226228
} else {
227-
_lspConnection.sendNotification(
229+
lspConnection.sendNotification(
228230
lsp.Method.initialized.toString(),
229231
lsp.InitializedParams().toJson(),
230232
);
@@ -235,8 +237,8 @@ base mixin DartAnalyzerSupport
235237
@override
236238
Future<void> shutdown() async {
237239
await super.shutdown();
238-
_lspServer.kill();
239-
await _lspConnection.close();
240+
_lspServer?.kill();
241+
await _lspConnection?.close();
240242
}
241243

242244
/// Implementation of the [analyzeFilesTool], analyzes all the files in all
@@ -270,7 +272,7 @@ base mixin DartAnalyzerSupport
270272
if (errorResult != null) return errorResult;
271273

272274
final query = request.arguments![ParameterNames.query] as String;
273-
final result = await _lspConnection.sendRequest(
275+
final result = await _lspConnection!.sendRequest(
274276
lsp.Method.workspace_symbol.toString(),
275277
lsp.WorkspaceSymbolParams(query: query).toJson(),
276278
);
@@ -288,7 +290,7 @@ base mixin DartAnalyzerSupport
288290
line: request.arguments![ParameterNames.line] as int,
289291
character: request.arguments![ParameterNames.column] as int,
290292
);
291-
final result = await _lspConnection.sendRequest(
293+
final result = await _lspConnection!.sendRequest(
292294
lsp.Method.textDocument_signatureHelp.toString(),
293295
lsp.SignatureHelpParams(
294296
textDocument: lsp.TextDocumentIdentifier(uri: uri),
@@ -309,7 +311,7 @@ base mixin DartAnalyzerSupport
309311
line: request.arguments![ParameterNames.line] as int,
310312
character: request.arguments![ParameterNames.column] as int,
311313
);
312-
final result = await _lspConnection.sendRequest(
314+
final result = await _lspConnection!.sendRequest(
313315
lsp.Method.textDocument_hover.toString(),
314316
lsp.HoverParams(
315317
textDocument: lsp.TextDocumentIdentifier(uri: uri),
@@ -396,7 +398,7 @@ base mixin DartAnalyzerSupport
396398
() => 'Notifying of workspace root change: ${event.toJson()}',
397399
);
398400

399-
_lspConnection.sendNotification(
401+
_lspConnection!.sendNotification(
400402
lsp.Method.workspace_didChangeWorkspaceFolders.toString(),
401403
lsp.DidChangeWorkspaceFoldersParams(event: event).toJson(),
402404
);

pkgs/dart_mcp_server/lib/src/server.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,12 +252,15 @@ Sink<String> _createLogSink(io.File logFile) {
252252
StreamSinkTransformer.fromHandlers(
253253
handleData: (data, innerSink) {
254254
innerSink.add(utf8.encode(data));
255-
// It's a log, so we want to make sure it's always up-to-date.
256-
fileByteSink.flush();
257255
},
258-
handleDone: (innerSink) {
256+
handleDone: (innerSink) async {
259257
innerSink.close();
260258
},
259+
handleError: (Object e, StackTrace s, _) {
260+
io.stderr.writeln(
261+
'Error in writing to log file ${logFile.path}: $e\n$s',
262+
);
263+
},
261264
),
262265
);
263266
}

pkgs/dart_mcp_server/test/dart_tooling_mcp_server_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void main() {
123123

124124
// Wait for the process to release the file.
125125
await doWithRetries(() => File(logDescriptor.io.path).delete());
126-
}, skip: 'https://github.com/dart-lang/ai/issues/181');
126+
});
127127
});
128128
}
129129

0 commit comments

Comments
 (0)