grover 1.1.9 → 1.1.11

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82b9a3edaa4f0d20c326f3e79d61b1d2a0190454ac9ffb6867191a9607ec1ea0
4
- data.tar.gz: 4e71234c41bf19c88a5b44c0a043a1c2ae5a74f94d0606fb0cd627c02e8511a2
3
+ metadata.gz: 07f9183a814d7d598e29ee39cc4d7af3df619ba262aa1bef5be2de0cd9e7da3c
4
+ data.tar.gz: 368d618c68428ff2f02832962463532a305ca48a2d6b8956dd978a80dc375052
5
5
  SHA512:
6
- metadata.gz: 737079399ecd8ef4c6a88c535495a2aa52fcb9e2e8fa0ca171d3453b58134d795237e606487a9f3dd06afad73baac8fac834a76a33445a1099e168f929f13835
7
- data.tar.gz: 767e6ebf33ce60336d9afd71859e004b54765910136387ed81b44a12489de7728ff88d0b5f33890dea45314a58476972d31a1f3e9e5e7834f6d68979acf0eb19
6
+ metadata.gz: 0deb217329f6141c3a7ed3da596945aa79213ca2216dbc914bb6b1e17104283bff1f8f45057f4fa099689fd8295560f9e0e2d023fa0e93551599a447649dace2
7
+ data.tar.gz: 6e9b91209b59e8bc91ef38aa42906468c2b79614950f6d9e345d002468248519a633b69cbaeb4e6ad6e520e5f8acafa2356e084c1b167ac7717c344a287bcd72
data/lib/grover/errors.rb CHANGED
@@ -11,6 +11,18 @@ class Grover
11
11
  module JavaScript # rubocop:disable Style/Documentation
12
12
  Error = Class.new(::Grover::Error)
13
13
  UnknownError = Class.new(Error)
14
+
15
+ ErrorWithDetails = Class.new(Error) do
16
+ def initialize(name, error_details)
17
+ super(name)
18
+ @error_details = Grover::Utils.deep_transform_keys_in_object error_details, &:to_sym
19
+ end
20
+
21
+ attr_reader :error_details
22
+ end
23
+ RequestFailedError = Class.new(ErrorWithDetails)
24
+ PageRenderError = Class.new(ErrorWithDetails)
25
+
14
26
  def self.const_missing(name)
15
27
  const_set name, Class.new(Error)
16
28
  end
@@ -26,8 +26,32 @@ const fs = require('fs');
26
26
  const os = require('os');
27
27
  const path = require('path');
28
28
 
29
+ function GroverError(name, errors) {
30
+ this.name = name;
31
+ this.message = errors.map(e => e.message).join("\n");
32
+ this.errors = errors;
33
+ }
34
+ GroverError.prototype = Error.prototype;
35
+
29
36
  const _processPage = (async (convertAction, uriOrHtml, options) => {
30
- let browser, page, errors = [], tmpDir, wsConnection = false;
37
+ let browser, page, tmpDir, wsConnection = false;
38
+ const requestErrors = [], pageErrors = [];
39
+
40
+ const captureRequestError = (request) => {
41
+ const requestError = { url: request.url() };
42
+
43
+ if (request.failure()) {
44
+ requestError.reason = request.failure().errorText;
45
+ requestError.message = requestError.reason + " at " + requestError.url;
46
+ } else if (request.response() && request.response().status()) {
47
+ requestError.status = request.response().status();
48
+ requestError.message = requestError.status + " " + requestError.url;
49
+ } else {
50
+ requestError.message = "UnknownError " + requestError.url;
51
+ }
52
+
53
+ requestErrors.push(requestError);
54
+ };
31
55
 
32
56
  try {
33
57
  // Configure puppeteer debugging options
@@ -163,12 +187,24 @@ const _processPage = (async (convertAction, uriOrHtml, options) => {
163
187
  const raiseOnRequestFailure = options.raiseOnRequestFailure; delete options.raiseOnRequestFailure;
164
188
  if (raiseOnRequestFailure) {
165
189
  page.on('requestfinished', (request) => {
166
- if (request.response() && !(request.response().ok() || request.response().status() === 304) && !request.redirectChain().length > 0) {
167
- errors.push(request);
190
+ if (request.response() &&
191
+ !(request.response().ok() || request.response().status() === 304) &&
192
+ !request.redirectChain().length > 0) {
193
+ captureRequestError(request);
168
194
  }
169
195
  });
170
196
  page.on('requestfailed', (request) => {
171
- errors.push(request);
197
+ captureRequestError(request);
198
+ });
199
+ }
200
+
201
+ const raiseOnJSError = options.raiseOnJSError; delete options.raiseOnJSError;
202
+ if (raiseOnJSError) {
203
+ page.on('pageerror', (error) => {
204
+ pageErrors.push({
205
+ message: error.toString().replace(new RegExp('^' + error.name + ': '), ''),
206
+ type: error.name || 'Error'
207
+ });
172
208
  });
173
209
  }
174
210
 
@@ -257,21 +293,12 @@ const _processPage = (async (convertAction, uriOrHtml, options) => {
257
293
  await page.hover(hoverSelector);
258
294
  }
259
295
 
260
- if (errors.length > 0) {
261
- function RequestFailedError(errors) {
262
- this.name = "RequestFailedError";
263
- this.message = errors.map(e => {
264
- if (e.failure()) {
265
- return e.failure().errorText + " at " + e.url();
266
- } else if (e.response() && e.response().status()) {
267
- return e.response().status() + " " + e.url();
268
- } else {
269
- return "UnknownError " + e.url()
270
- }
271
- }).join("\n");
272
- }
273
- RequestFailedError.prototype = Error.prototype;
274
- throw new RequestFailedError(errors);
296
+ if (requestErrors.length > 0) {
297
+ throw new GroverError("RequestFailedError", requestErrors);
298
+ }
299
+
300
+ if (pageErrors.length > 0) {
301
+ throw new GroverError("PageRenderError", pageErrors);
275
302
  }
276
303
 
277
304
  // Setup conversion timeout
@@ -282,7 +309,7 @@ const _processPage = (async (convertAction, uriOrHtml, options) => {
282
309
 
283
310
  // If we're running puppeteer in headless mode, return the converted PDF
284
311
  if (debug === undefined || (typeof debug === 'object' && (debug.headless === undefined || debug.headless))) {
285
- return await page[convertAction](options);
312
+ return Buffer.from(await page[convertAction](options));
286
313
  }
287
314
  } finally {
288
315
  if (browser) {
@@ -301,7 +328,9 @@ const _processPage = (async (convertAction, uriOrHtml, options) => {
301
328
  });
302
329
 
303
330
  function _handleError(error) {
304
- if (error instanceof Error) {
331
+ if (error instanceof GroverError) {
332
+ process.stdout.write(JSON.stringify(['err', error.message, error.name, error.errors]));
333
+ } else if (error instanceof Error) {
305
334
  process.stdout.write(
306
335
  JSON.stringify(['err', error.toString().replace(new RegExp('^' + error.name + ': '), ''), error.name])
307
336
  );
@@ -34,7 +34,8 @@ class Grover
34
34
  def fix_boolean_options!
35
35
  fix_options!(
36
36
  'display_header_footer', 'full_page', 'landscape', 'omit_background', 'prefer_css_page_size',
37
- 'print_background', 'viewport.has_touch', 'viewport.is_landscape', 'viewport.is_mobile', 'bypass_csp'
37
+ 'print_background', 'viewport.has_touch', 'viewport.is_landscape', 'viewport.is_mobile', 'bypass_csp',
38
+ 'raise_on_request_failure', 'raise_on_js_error'
38
39
  ) { |value| !FALSE_VALUES.include?(value) }
39
40
  end
40
41
 
@@ -83,14 +83,14 @@ class Grover
83
83
  input = stdout.gets
84
84
  raise Errno::EPIPE, "Can't read from worker" if input.nil?
85
85
 
86
- status, message, error_class = JSON.parse(input)
86
+ status, message, error_class, errors = JSON.parse(input)
87
87
 
88
88
  if status == 'ok'
89
89
  message
90
90
  elsif error_class.nil?
91
91
  raise Grover::JavaScript::UnknownError, message
92
92
  else
93
- raise Grover::JavaScript.const_get(error_class, false), message
93
+ raise Grover::JavaScript.const_get(error_class, false).new(*[message, errors].compact)
94
94
  end
95
95
  rescue JSON::ParserError
96
96
  raise Grover::Error, 'Malformed worker response'
data/lib/grover/utils.rb CHANGED
@@ -8,7 +8,8 @@ class Grover
8
8
  ACRONYMS = {
9
9
  'css' => 'CSS',
10
10
  'csp' => 'CSP',
11
- 'http' => 'HTTP'
11
+ 'http' => 'HTTP',
12
+ 'js' => 'JS'
12
13
  }.freeze
13
14
  private_constant :ACRONYMS
14
15
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Grover
4
- VERSION = '1.1.9'
4
+ VERSION = '1.1.11'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grover
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.9
4
+ version: 1.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Bromwich
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-02 00:00:00.000000000 Z
11
+ date: 2024-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: combine_pdf