@@ -36,21 +36,42 @@ object PosixPluginFrontend extends PluginFrontend {
36
36
37
37
Future {
38
38
blocking {
39
- System .err.println(" Files.newInputStream..." )
40
- val fsin = Files .newInputStream(inputPipe)
41
- System .err.println(" PluginFrontend.runWithInputStream..." )
42
- val response = PluginFrontend .runWithInputStream(plugin, fsin, env)
43
- System .err.println(" fsin.close..." )
44
- fsin.close()
39
+ try {
40
+ System .err.println(" Files.newInputStream..." )
41
+ val fsin = Files .newInputStream(inputPipe)
42
+ System .err.println(" PluginFrontend.runWithInputStream..." )
43
+ val response = PluginFrontend .runWithInputStream(plugin, fsin, env)
44
+ System .err.println(" fsin.close..." )
45
+ fsin.close()
45
46
46
- System .err.println(" Files.newOutputStream..." )
47
- val fsout = Files .newOutputStream(outputPipe)
48
- System .err.println(" fsout.write..." )
49
- fsout.write(response)
50
- System .err.println(" fsout.close..." )
51
- fsout.close()
47
+ System .err.println(" Files.newOutputStream..." )
48
+ val fsout = Files .newOutputStream(outputPipe)
49
+ System .err.println(" fsout.write..." )
50
+ fsout.write(response)
51
+ System .err.println(" fsout.close..." )
52
+ fsout.close()
52
53
53
- System .err.println(" blocking done." )
54
+ System .err.println(" blocking done." )
55
+ } catch {
56
+ case e : Throwable =>
57
+ // Handles rare exceptions not already gracefully handled in `runWithBytes`.
58
+ // Such exceptions aren't converted to `CodeGeneratorResponse`
59
+ // because `fsin` might not be fully consumed,
60
+ // therefore the plugin shell script might hang on `inputPipe`,
61
+ // and never consume `CodeGeneratorResponse`.
62
+ System .err.println(" Exception occurred in PluginFrontend outside runWithBytes" )
63
+ e.printStackTrace(System .err)
64
+ // Force an exit of the program.
65
+ // This is because the plugin shell script might hang on `inputPipe`,
66
+ // due to `fsin` not fully consumed.
67
+ // Or it might hang on `outputPipe`, due to `fsout` not closed.
68
+ // We can't simply close `fsout` here either,
69
+ // because `Files.newOutputStream(outputPipe)` will hang
70
+ // if `outputPipe` is not yet opened by the plugin shell script for reading.
71
+ // Therefore, the program might be stuck waiting for protoc,
72
+ // which in turn is waiting for the plugin shell script.
73
+ sys.exit(1 )
74
+ }
54
75
}
55
76
}
56
77
(sh, InternalState (inputPipe, outputPipe, tempDirPath, sh))
0 commit comments