grover 1.1.9 → 1.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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