shelf icon indicating copy to clipboard operation
shelf copied to clipboard

Propagate error messages to the user's error handler instead of printing them to the console

Open annagrin opened this issue 3 years ago • 2 comments

See user's output of running webdev in https://github.com/dart-lang/webdev/issues/1520

Looks like the _logError currently always prints error messages to the console, even if the current error zone is different from the root zone. Would it be possible to propagate them to the current error zone's handler instead, or invent some other mechanism to prevent it from printing to the console?

https://github.com/dart-lang/shelf/blob/c53cb8d07931a4a1ce2a97a0a07e284804cfec33/lib/shelf_io.dart#L129

Here is how webdev defines the error zone and the error handler. The messages above do not seem to propagate to it:

https://github.com/dart-lang/webdev/blob/47dd82ccd63afd600276fba0bf4f64019258e9a6/webdev/lib/src/serve/webdev_server.dart#L189

https://github.com/dart-lang/webdev/blob/00832f8654fcf969322063f017a2ad0f583a2f41/webdev/lib/src/util.dart#L21

Example


import 'dart:async';
import 'dart:io';
import 'dart:convert';

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:http_multi_server/http_multi_server.dart';

void main() async {
  var port = 44459;
  var server = await await HttpMultiServer.bind('localhost', port);
  serveHttpRequests(server, (request) {
    throw StateError('from handler');
  }, (e,s) {
    print('Async error from error zone: $e:$s');
  });

  print('Sending request...');
  var client = HttpClient();
  var request = await client.openUrl('GET', Uri.parse('http://127.0.0.1:$port/index.html'));
  var response = await request.close();

  response.transform(utf8.decoder).listen((event) {
    print('Response: ${event}');
  });

  Future.delayed(Duration(milliseconds: 100));

  client.close();
  await server.close();
  print('done');
}

void serveHttpRequests(Stream<HttpRequest> requests, Handler handler,
    void Function(Object, StackTrace) onError) {
  return Chain.capture(() {
    serveRequests(requests, handler);
  }, onError: onError);
}

Console output

Sending request...
ERROR - 2022-05-06 13:41:57.044187
GET /index.html
Error thrown by handler.
Bad state: from handler
main.dart 14:5                     main.<fn>
package:shelf/shelf_io.dart 75:34  serveRequests.<fn>.<fn>
===== asynchronous gap ===========================
package:shelf/shelf_io.dart 74:3   serveRequests
main.dart 38:5                     serveHttpRequests.<fn>
package:stack_trace                Chain.capture
main.dart 37:16                    serveHttpRequests
main.dart 13:3                     main

Response: Internal Server Error
done

Expected

Error reported from my error handler, printing "Async error from error zone..."

annagrin avatar May 06 '22 20:05 annagrin

Also, it would be great if the code providing the error handler could tell the severity of the errors so we can report them differently to the user, ie with different levels of severity.

annagrin avatar May 06 '22 20:05 annagrin

Do we have any more thoughts here? @natebosch ?

kevmoo avatar Oct 01 '22 03:10 kevmoo