From 631e516e4e8edc98b6f7a0783c97fd2ce0520aa1 Mon Sep 17 00:00:00 2001 From: Mike Bland Date: Sun, 20 Oct 2024 18:57:05 -0400 Subject: [PATCH] Catch Throwable in ExtraProtobufGenerator Added a `catch` case for `Throwable` in `handleCodeGeneratorRequest`. Part of #1482. Not catching this caused `ProtoScalaPBRule` workers to hang when building `//test/...` after bumping com_google_protobuf from 25.5 to 27.5. With this change, we can now see the error: ```txt $ USE_BAZEL_VERSION=7.3.2 bazel build //test/... ERROR: .../test/proto/BUILD:165:14: ProtoScalaPBRule test/proto/standalone_proto_strip_import_prefix_package_jvm_extra_protobuf_generator_scalapb.srcjar failed: (Exit 1): scalapb_worker failed: error executing ProtoScalaPBRule command (from target //test/proto:standalone_proto_strip_import_prefix_package) bazel-bin/src/scala/scripts/scalapb_worker ... (remaining 2 arguments skipped) --jvm_extra_protobuf_generator_out: java.lang.NoSuchMethodError: 'java.lang.Object com.google.protobuf.DescriptorProtos$MessageOptions.getExtension(com.google.protobuf.GeneratedMessage$GeneratedExtension)' at scalapb.compiler.DescriptorImplicits$ExtendedMessageDescriptor.messageOptions(DescriptorImplicits.scala:532) at scalapb.compiler.DescriptorImplicits$ExtendedMessageDescriptor.sealedOneOfExtendsCount(DescriptorImplicits.scala:578) at scalapb.compiler.ProtoValidation.validateMessage(ProtoValidation.scala:107) at scalapb.compiler.ProtoValidation.$anonfun$validateFile$2(ProtoValidation.scala:17) at scalapb.compiler.ProtoValidation.$anonfun$validateFile$2$adapted(ProtoValidation.scala:17) at scala.collection.Iterator.foreach(Iterator.scala:943) at scala.collection.Iterator.foreach$(Iterator.scala:943) at scala.collection.AbstractIterator.foreach(Iterator.scala:1431) at scala.collection.IterableLike.foreach(IterableLike.scala:74) at scala.collection.IterableLike.foreach$(IterableLike.scala:73) at scala.collection.AbstractIterable.foreach(Iterable.scala:56) at scalapb.compiler.ProtoValidation.validateFile(ProtoValidation.scala:17) at scalapb.compiler.ProtoValidation.$anonfun$validateFiles$1(ProtoValidation.scala:10) at scalapb.compiler.ProtoValidation.$anonfun$validateFiles$1$adapted(ProtoValidation.scala:10) at scala.collection.immutable.Stream.foreach(Stream.scala:533) at scalapb.compiler.ProtoValidation.validateFiles(ProtoValidation.scala:10) at scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator$.handleCodeGeneratorRequest(ExtraProtobufGenerator.scala:65) at scalarules.test.extra_protobuf_generator.ExtraProtobufGenerator$.run(ExtraProtobufGenerator.scala:47) at protocbridge.frontend.PluginFrontend$.$anonfun$runWithBytes$1(PluginFrontend.scala:51) at scala.util.Try$.apply(Try.scala:213) at protocbridge.frontend.PluginFrontend$.runWithBytes(PluginFrontend.scala:51) at protocbridge.frontend.PluginFrontend$.runWithInputStream(PluginFrontend.scala:121) at protocbridge.frontend.PosixPluginFrontend$.$anonfun$prepare$2(PosixPluginFrontend.scala:40) at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23) at scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$1$$anon$2.block(ExecutionContextImpl.scala:75) at java.base/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3118) at scala.concurrent.impl.ExecutionContextImpl$DefaultThreadFactory$$anon$1.blockOn(ExecutionContextImpl.scala:87) at scala.concurrent.package$.blocking(package.scala:146) at protocbridge.frontend.PosixPluginFrontend$.$anonfun$prepare$1(PosixPluginFrontend.scala:38) at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.java:23) at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:659) at scala.util.Success.$anonfun$map$1(Try.scala:255) at scala.util.Success.map(Try.scala:213) at scala.concurrent.Future.$anonfun$map$1(Future.scala:292) at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:42) at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:74) at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1426) at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020) at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656) at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594) at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183) java.lang.RuntimeException: Exit with code 1 at scala.sys.package$.error(package.scala:30) at scripts.ScalaPBWorker$.work(ScalaPBWorker.scala:44) at io.bazel.rulesscala.worker.Worker.persistentWorkerMain(Worker.java:96) at io.bazel.rulesscala.worker.Worker.workerMain(Worker.java:49) at scripts.ScalaPBWorker$.main(ScalaPBWorker.scala:39) at scripts.ScalaPBWorker.main(ScalaPBWorker.scala) ERROR: .../test/proto/BUILD:165:14 scala @//test/proto:standalone_proto_strip_import_prefix_package failed: (Exit 1): scalapb_worker failed: error executing ProtoScalaPBRule command (from target //test/proto:standalone_proto_strip_import_prefix_package) bazel-out/darwin_arm64-opt-exec-ST-a828a81199fe/bin/src/scala/scripts/scalapb_worker ... (remaining 2 arguments skipped) ``` The fix for this is to bump ScalaPB jar versions to 1.0.0-alpha.1, which will come in a future change. --- .../ExtraProtobufGenerator.scala | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/src/main/scala/scalarules/test/extra_protobuf_generator/ExtraProtobufGenerator.scala b/test/src/main/scala/scalarules/test/extra_protobuf_generator/ExtraProtobufGenerator.scala index 79629a7a1..4cd4f932e 100644 --- a/test/src/main/scala/scalarules/test/extra_protobuf_generator/ExtraProtobufGenerator.scala +++ b/test/src/main/scala/scalarules/test/extra_protobuf_generator/ExtraProtobufGenerator.scala @@ -47,7 +47,7 @@ object ExtraProtobufGenerator extends ProtocCodeGenerator { handleCodeGeneratorRequest(request).toByteArray } - def handleCodeGeneratorRequest(request: CodeGeneratorRequest): CodeGeneratorResponse = { + def handleCodeGeneratorRequest(request: CodeGeneratorRequest): CodeGeneratorResponse = { val b = CodeGeneratorResponse.newBuilder ProtobufGenerator.parseParameters(request.getParameter) match { case Right(params) => @@ -73,6 +73,13 @@ object ExtraProtobufGenerator extends ProtocCodeGenerator { } catch { case e: GeneratorException => b.setError(e.message) + case e: Throwable => + // Yes, we want to catch _all_ errors and send them back to the + // requestor. Otherwise uncaught errors will cause the generator to + // die and the worker invoking it to hang. + val stackStream = new java.io.ByteArrayOutputStream + e.printStackTrace(new java.io.PrintStream(stackStream)) + b.setError(stackStream.toString()) } case Left(error) => b.setError(error)