Current section
Files
Jump to
Current section
Files
lib/gear_application/error_handler.ex
# Copyright(c) 2015-2018 ACCESS CO., LTD. All rights reserved.
use Croma
defmodule Antikythera.GearApplication.ErrorHandler do
@moduledoc """
Helper module for gear's custom error handler.
To customize HTTP responses returned on errors, gear must implement an error handler module which
- is named `YourGear.Controller.Error`, and
- defines the following functions:
- Mandatory error handlers
- `error/2`
- `no_route/1`
- `bad_request/1`
- Optional error handlers (when your gear uses websocket)
- `ws_too_many_connections/1`
This module generates `YourGear.error_handler_module/0` function, which is called by antikythera when handling errors.
"""
alias Antikythera.GearName
alias AntikytheraCore.GearModule
@all_handlers [
error: 2,
no_route: 1,
bad_request: 1,
]
@doc false
defun find_error_handler_module(gear_name :: v[GearName.t]) :: nil | module do
mod = GearModule.error_handler_unsafe(gear_name) # during compilation of gear, allowed to call unsafe function
try do
exported_funs = mod.module_info(:exports)
not_defined_handlers = Enum.reject(@all_handlers, &(&1 in exported_funs))
if Enum.empty?(not_defined_handlers) do
mod
else
IO.puts("""
[antikythera] warning: #{mod} exists but some of the error handlers are not defined: #{inspect(not_defined_handlers)};
[antikythera] #{mod} is not eligible for a custom error handler module.
""")
nil
end
rescue
UndefinedFunctionError -> nil # module not defined
end
end
defmacro __using__(_) do
quote do
# Assuming that module attribute `@gear_name` is defined in the __CALLER__'s context
@error_handler_module Antikythera.GearApplication.ErrorHandler.find_error_handler_module(@gear_name)
defun error_handler_module() :: nil | module do
@error_handler_module
end
end
end
end