@@ -184,9 +184,8 @@ public ProtocolResponse getProtocolOutput(String url, Metadata md) throws Except
184184
185185 // https://github.com/microsoft/playwright-java#is-playwright-thread-safe
186186 synchronized (this ) {
187-
188- // tracing// Start tracing before creating / navigating a page.
189- if (md .containsKey (MD_TRACE )) {
187+ boolean isTracing = md .containsKey (MD_TRACE );
188+ if (isTracing ) {
190189 context .tracing ()
191190 .start (
192191 new Tracing .StartOptions ()
@@ -201,109 +200,120 @@ public ProtocolResponse getProtocolOutput(String url, Metadata md) throws Except
201200 final MutableInt status = new MutableInt (-1 );
202201 byte [] content = new byte [0 ];
203202
204- try (Page page = context .newPage ()) {
205-
206- page .onResponse (
207- response -> {
208- // make sure that this applies to the main page
209- if (response .url ().equals (url )) {
210- // redirection?
211- if (Status .REDIRECTION .equals (
212- Status .fromHTTPCode (response .status ()))) {
213- status .set (response .status ());
214- response .allHeaders ()
215- .forEach (
216- (k , v ) -> {
217- responseMetaData .addValue (k , v );
218- });
203+ try {
204+ try (Page page = context .newPage ()) {
205+
206+ page .onResponse (
207+ response -> {
208+ // make sure that this applies to the main page
209+ if (response .url ().equals (url )) {
210+ // redirection?
211+ if (Status .REDIRECTION .equals (
212+ Status .fromHTTPCode (response .status ()))) {
213+ status .set (response .status ());
214+ response .allHeaders ()
215+ .forEach (
216+ (k , v ) -> {
217+ responseMetaData .addValue (k , v );
218+ });
219+ }
219220 }
220- }
221- });
222-
223- page .onPageError (
224- handler -> {
225- // this applies to any resource - not just the main page
226- LOG .debug ("Error when loading {} {}" , url , handler );
227- });
228-
229- // NOTE: The handler will only be called for the first url if the
230- // response is a redirect.
231- page .route (
232- lambdaUrl -> true ,
233- route -> {
234- // abort if we know the main page is a redirection
235- if (status .get () != -1 ) {
236- LOG .debug ("Aborting request for {}" , route .request ().url ());
237- route .abort ();
238- } else if (resourceTypesToSkip .contains (
239- route .request ().resourceType ())) {
240- route .abort ();
241- } else {
242- route .resume ();
243- }
244- });
245-
246- // let playwright do the content loading
247- com .microsoft .playwright .Response response =
248- page .navigate (
249- url ,
250- new Page .NavigateOptions ()
251- .setTimeout (timeout )
252- .setWaitUntil (loadEvent ));
253-
254- // the status is not set unless
255- // a redirection
256- if (status .get () == -1 ) {
257- response .allHeaders ()
258- .forEach (
259- (k , v ) -> {
260- responseMetaData .addValue (k , v );
261- });
262-
263- int httpStatus = response .status ();
264- boolean fetched = Status .FETCHED == Status .fromHTTPCode (httpStatus );
265- boolean contentCaptured = false ;
266-
267- if (fetched || captureContentOnError ) {
268- // run any configured post-navigate actions before capturing content
269- pageActions .apply (page , url , md , responseMetaData );
270- // retrieve the rendered content
271- content = page .content ().getBytes (StandardCharsets .UTF_8 );
272- contentCaptured = true ;
273- }
221+ });
222+
223+ page .onPageError (
224+ handler -> {
225+ // this applies to any resource - not just the main page
226+ LOG .debug ("Error when loading {} {}" , url , handler );
227+ });
228+
229+ // NOTE: The handler will only be called for the first url if the
230+ // response is a redirect.
231+ page .route (
232+ lambdaUrl -> true ,
233+ route -> {
234+ // abort if we know the main page is a redirection
235+ if (status .get () != -1 ) {
236+ LOG .debug ("Aborting request for {}" , route .request ().url ());
237+ route .abort ();
238+ } else if (resourceTypesToSkip .contains (
239+ route .request ().resourceType ())) {
240+ route .abort ();
241+ } else {
242+ route .resume ();
243+ }
244+ });
245+
246+ // let playwright do the content loading
247+ com .microsoft .playwright .Response response =
248+ page .navigate (
249+ url ,
250+ new Page .NavigateOptions ()
251+ .setTimeout (timeout )
252+ .setWaitUntil (loadEvent ));
253+
254+ // the status is not set unless
255+ // a redirection
256+ if (status .get () == -1 ) {
257+ response .allHeaders ()
258+ .forEach (
259+ (k , v ) -> {
260+ responseMetaData .addValue (k , v );
261+ });
262+
263+ int httpStatus = response .status ();
264+ boolean fetched = Status .FETCHED == Status .fromHTTPCode (httpStatus );
265+ boolean contentCaptured = false ;
266+
267+ if (fetched || captureContentOnError ) {
268+ // run any configured post-navigate actions before capturing content
269+ pageActions .apply (page , url , md , responseMetaData );
270+ // retrieve the rendered content
271+ content = page .content ().getBytes (StandardCharsets .UTF_8 );
272+ contentCaptured = true ;
273+ }
274274
275- if (!fetched && contentCaptured && overrideStatusOnContent ) {
276- // expose the original origin status for diagnostics
277- responseMetaData .setValue (
278- "playwright.origin.status" , Integer .toString (httpStatus ));
279- status .set (200 );
280- } else {
281- status .set (httpStatus );
282- }
275+ if (!fetched && contentCaptured && overrideStatusOnContent ) {
276+ // expose the original origin status for diagnostics
277+ responseMetaData .setValue (
278+ "playwright.origin.status" , Integer .toString (httpStatus ));
279+ status .set (200 );
280+ } else {
281+ status .set (httpStatus );
282+ }
283283
284- // evaluate an expression and store the results
285- // in the metadata using the same string as key
286- for (String expression : evaluations ) {
287- Object performance = page .evaluate (expression );
288- if (performance != null ) {
289- String json =
290- mapper .writerWithDefaultPrettyPrinter ()
291- .writeValueAsString (performance );
292- responseMetaData .setValue (expression , json );
284+ // evaluate an expression and store the results
285+ // in the metadata using the same string as key
286+ for (String expression : evaluations ) {
287+ Object performance = page .evaluate (expression );
288+ if (performance != null ) {
289+ String json =
290+ mapper .writerWithDefaultPrettyPrinter ()
291+ .writeValueAsString (performance );
292+ responseMetaData .setValue (expression , json );
293+ }
293294 }
294295 }
295296 }
296- }
297297
298- if (md . containsKey ( MD_TRACE ) ) {
299- Path tmp = Files .createTempFile ("trace-" , ".zip" , new FileAttribute [0 ]);
300- context .tracing ().stop (new Tracing .StopOptions ().setPath (tmp ));
301- responseMetaData .setValue (MD_TRACE , tmp .toString ());
302- }
298+ if (isTracing ) {
299+ Path tmp = Files .createTempFile ("trace-" , ".zip" , new FileAttribute [0 ]);
300+ context .tracing ().stop (new Tracing .StopOptions ().setPath (tmp ));
301+ responseMetaData .setValue (MD_TRACE , tmp .toString ());
302+ }
303303
304- responseMetaData .addValue (MD_KEY_END , Instant .now ().toString ());
304+ responseMetaData .addValue (MD_KEY_END , Instant .now ().toString ());
305305
306- return new ProtocolResponse (content , status .get (), responseMetaData );
306+ return new ProtocolResponse (content , status .get (), responseMetaData );
307+
308+ } finally {
309+ if (isTracing && responseMetaData .getFirstValue (MD_TRACE ) == null ) {
310+ try {
311+ context .tracing ().stop (new Tracing .StopOptions ());
312+ } catch (Exception e ) {
313+ LOG .warn ("Exception while stopping tracing on error" , e );
314+ }
315+ }
316+ }
307317 }
308318 }
309319
0 commit comments