Skip to content

Commit

Permalink
more readable and extensible error messages, support for chrome_path.
Browse files Browse the repository at this point in the history
  • Loading branch information
gutschilla committed Apr 29, 2019
1 parent 7fdf481 commit d91a5aa
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 19 deletions.
11 changes: 7 additions & 4 deletions lib/pdf_generator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ defmodule PdfGenerator do
## Options
* `:generator` – either `chrome` or `wkhtmltopdf` (default)
* `:prefer_system_executable` - set to `true` if you installed
chrome-headless-render-pdf globally
* `:no_sandbox` – disable sandbox for chrome, required to run as root (read: _docker_)
* `:page_size` - output page size, defaults to "A4"
* `:open_password` - password required to open PDF. Will apply encryption to PDF
Expand Down Expand Up @@ -134,14 +136,15 @@ defmodule PdfGenerator do
with {html_file, pdf_file} <- make_file_paths(options),
:ok <- maybe_write_html(content, html_file),
{executable, arguments} <- make_command(generator, options, content, {html_file, pdf_file}),
{console_stderr, exit_code} <- System.cmd(executable, arguments, stderr_to_stdout: true), # unfortuantely wkhtmltopdf returns 0 on errors as well :-/
{:result_ok, true} <- {:result_ok, result_ok(generator, console_stderr, exit_code)}, # so we inspect stderr instead
{:cmd, {stderr, exit_code}} <- {:cmd, System.cmd(executable, arguments, stderr_to_stdout: true)}, # unfortuantely wkhtmltopdf returns 0 on errors as well :-/
{:result_ok, true, stderr} <- {:result_ok, result_ok(generator, stderr, exit_code), stderr}, # so we inspect stderr instead
{:rm, :ok} <- {:rm, maybe_delete_temp(delete_temp, html_file)},
{:ok, encrypted_pdf} <- maybe_encrypt_pdf(pdf_file, open_password, edit_password) do
{:ok, encrypted_pdf}
else
{:error, reason} -> {:error, reason}
reason -> {:error, reason}
{:error, reason} -> {:error, reason}
{:result_ok, _, stderr} -> {:error, {:generator_failed, stderr}}
reason -> {:error, reason}
end
end

Expand Down
44 changes: 29 additions & 15 deletions lib/pdf_generator_path_agent.ex
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
defmodule PdfGenerator.PathAgent do
require Logger
defstruct wkhtml_path: nil, pdftk_path: nil
defstruct [
wkhtml_path: nil,
pdftk_path: nil,
chrome: nil,
]

@moduledoc """
Will check system requirements on startup and keep
a path map as state in an Agent process.
Will check for system executables at startup time and store paths. If
configured as such, will raise an error when no usable executable was found.
"""

@name __MODULE__
Expand All @@ -17,8 +21,9 @@ defmodule PdfGenerator.PathAgent do
# options override system default paths
options =
[
wkhtml_path: System.find_executable( "wkhtmltopdf" ),
pdftk_path: System.find_executable( "pdftk" )
wkhtml_path: System.find_executable("wkhtmltopdf"),
pdftk_path: System.find_executable("pdftk"),
chrome_path: System.find_executable("chrome-headless-render-pdf"),
]
++ paths_from_options
|> Enum.dedup()
Expand All @@ -39,15 +44,24 @@ defmodule PdfGenerator.PathAgent do
end

def raise_or_continue(options) do
exe_exists = File.exists?(Keyword.get(options, :wkhtml_path, ""))
raise_on_missing = Keyword.get(options, :raise_on_missing_wkhtmltopdf_binary, true)

case {exe_exists, raise_on_missing} do
{true, _} -> options
{false, true} -> raise "wkhtmltopdf executable was not found on your system"
{false, false} ->
Logger.warn "wkhtmltopdf executable was not found on your system"
options
end
wkhtml_exists = File.exists?(options[:wkhtml_path])
chrome_exists = File.exists?(options[:chrome_path])

raise_on_wkhtml_missing = options[:raise_on_missing_wkhtmltopdf_binary]
raise_on_chrome_missing = options[:raise_on_missing_chrome_binary]
raise_on_any_missing = options[:raise_on_missing_binaries]

maybe_raise(:wkhtml, raise_on_wkhtml_missing, wkhtml_exists)
maybe_raise(:chrome, raise_on_chrome_missing, chrome_exists)
maybe_raise(:any, raise_on_any_missing, wkhtml_exists or chrome_exists)
end

defp maybe_raise(generator, config_says_raise = true, wkhtml_exists = false), do: generator |> missing_message() |> raise()
defp maybe_raise(generator, config_says_raise = false, wkhtml_exists = false), do: generator |> missing_message() |> Logger.warn()
defp maybe_raise(generator, config_says_raise = _, wkhtml_exists = _ ), do: :noop

defp missing_message(:wkhtml), do: "wkhtmltopdf executable was not found on your system"
defp missing_message(:chrome), do: "chrome-headless-render-pdf executable was not found on your system"
defp missing_message(:any), do: "neither wkhtmltopdf or chrome-headless-render-pdf executables were found on your system"

end

0 comments on commit d91a5aa

Please sign in to comment.