Skip to content
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

Use a common error handler for embedded protocol errors #2027

Merged
merged 2 commits into from
Jun 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 2 additions & 19 deletions lib/src/embedded/dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import 'dart:typed_data';
import 'package:path/path.dart' as p;
import 'package:protobuf/protobuf.dart';
import 'package:sass/sass.dart' as sass;
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/stream_channel.dart';

import 'embedded_sass.pb.dart';
Expand Down Expand Up @@ -116,24 +115,8 @@ class Dispatcher {
throw parseError(
"Unknown message type: ${message.toDebugString()}");
}
} on ProtocolError catch (error) {
// Always set the ID to [errorId] because we're only ever reporting
// errors for responses or for [CompileRequest] which has no ID.
error.id = errorId;
stderr.write("Host caused ${error.type.name.toLowerCase()} error");
if (error.id != errorId) stderr.write(" with request ${error.id}");
stderr.writeln(": ${error.message}");
sendError(error);
// PROTOCOL error from https://bit.ly/2poTt90
exitCode = 76;
_channel.sink.close();
} catch (error, stackTrace) {
var errorMessage = "$error\n${Chain.forTrace(stackTrace)}";
stderr.write("Internal compiler error: $errorMessage");
sendError(ProtocolError()
..type = ProtocolErrorType.INTERNAL
..id = errorId
..message = errorMessage);
} on ProtocolError catch (error, stackTrace) {
sendError(handleError(error, stackTrace));
_channel.sink.close();
}
}).asFuture<void>();
Expand Down
8 changes: 2 additions & 6 deletions lib/src/embedded/host_callable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

// ignore: deprecated_member_use
import 'dart:cli';
import 'dart:io';

import '../callable.dart';
import '../exception.dart';
Expand Down Expand Up @@ -51,11 +50,8 @@ Callable hostCallable(
case InboundMessage_FunctionCallResponse_Result.notSet:
throw mandatoryError('FunctionCallResponse.result');
}
} on ProtocolError catch (error) {
error.id = errorId;
stderr.writeln("Host caused ${error.type.name.toLowerCase()} error: "
"${error.message}");
dispatcher.sendError(error);
} on ProtocolError catch (error, stackTrace) {
dispatcher.sendError(handleError(error, stackTrace));
throw error.message;
}
});
Expand Down
25 changes: 3 additions & 22 deletions lib/src/embedded/isolate_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

import 'dart:async';
import 'dart:ffi';
import 'dart:io';
import 'dart:isolate';
import 'dart:typed_data';

import 'package:pool/pool.dart';
import 'package:protobuf/protobuf.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:stream_channel/isolate_channel.dart';
import 'package:stream_channel/stream_channel.dart';

Expand Down Expand Up @@ -199,26 +197,9 @@ class IsolateDispatcher {
/// responded to, if available.
void _handleError(Object error, StackTrace stackTrace,
{int? compilationId, int? messageId}) {
if (error is ProtocolError) {
error.id = messageId ?? errorId;
stderr.write("Host caused ${error.type.name.toLowerCase()} error");
if (error.id != errorId) stderr.write(" with request ${error.id}");
stderr.writeln(": ${error.message}");
sendError(compilationId ?? errorId, error);
// PROTOCOL error from https://bit.ly/2poTt90
exitCode = 76;
_channel.sink.close();
} else {
var errorMessage = "$error\n${Chain.forTrace(stackTrace)}";
stderr.write("Internal compiler error: $errorMessage");
sendError(
compilationId ?? errorId,
ProtocolError()
..type = ProtocolErrorType.INTERNAL
..id = messageId ?? errorId
..message = errorMessage);
_channel.sink.close();
}
sendError(compilationId ?? errorId,
handleError(error, stackTrace, messageId: messageId));
_channel.sink.close();
}

/// Sends [message] to the host.
Expand Down
24 changes: 24 additions & 0 deletions lib/src/embedded/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// MIT-style license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT.

import 'dart:io';
import 'dart:typed_data';

import 'package:protobuf/protobuf.dart';
import 'package:source_span/source_span.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:term_glyph/term_glyph.dart' as term_glyph;

import '../syntax.dart';
Expand Down Expand Up @@ -134,3 +136,25 @@ final _compilationIdBuilder = VarintBuilder(32, 'compilation ID');
_compilationIdBuilder.reset();
}
}

/// Wraps error object into ProtocolError, writes error to stderr, and returns the ProtocolError.
ProtocolError handleError(Object error, StackTrace stackTrace,
{int? messageId}) {
if (error is ProtocolError) {
error.id = messageId ?? errorId;
stderr.write("Host caused ${error.type.name.toLowerCase()} error");
if (error.id != errorId) stderr.write(" with request ${error.id}");
stderr.writeln(": ${error.message}");
// PROTOCOL error from https://bit.ly/2poTt90
exitCode = 76; // EX_PROTOCOL
return error;
} else {
var errorMessage = "$error\n${Chain.forTrace(stackTrace)}";
stderr.write("Internal compiler error: $errorMessage");
exitCode = 70; // EX_SOFTWARE
return ProtocolError()
..type = ProtocolErrorType.INTERNAL
..id = messageId ?? errorId
..message = errorMessage;
}
}