Skip to content

Instantly share code, notes, and snippets.

@sultaniman
sultaniman / dynamic-supervisor-via-registry.ex
Created April 30, 2020 17:35
How to create dynamic supervisor with registry
# Your actual dynamic worker
defmodule Awesome.Worker do
use GenServer, restart: :transient
alias Awesome.Hero
# Client
def start_link(%Hero{} = hero), do:
GenServer.start_link(@mod, hero, name: proc_name(hero))
defp proc_name(%Hero{name: name}), do:
def from_packages_list(data: str) -> Generator:
"""Parses CRAN package metadata from
https://cran.r-project.org/src/contrib/PACKAGES
and returns the list of dictionaries.
Args:
data (str): raw text from the package list
Returns:
(Generator): each entry from packages as dictionary
@sultaniman
sultaniman / process_errors_helper.ex
Last active May 7, 2019 21:32
process errors helper
def process_errors(%Changeset{} = changeset) do
%{
message: "Changeset errors occurred",
code: :schema_errors,
errors: to_api_errors(changeset)
}
end
# add this to your schema module
# if it's a field for the mutation object, add this middleware to the end
def middleware(middleware, _field, %{identifier: :mutation}) do
middleware ++ [Idp.Middlewares.HandleAPIErrors]
end
# if it's any other object keep things as is
def middleware(middleware, _field, _object), do: middleware
@sultaniman
sultaniman / absinthe-middleware-handle-errors.ex
Last active May 7, 2019 21:31
Absinthe middleware handle to handle errors
defmodule Idp.Middlewares.HandleAPIErrors do
@behaviour Absinthe.Middleware
alias Idp.EctoHelpers
def call(resolution, _config) do
errors =
resolution
|> Map.get(:errors)
|> Enum.flat_map(&process_errors/1)
@sultaniman
sultaniman / absinthe-resolver-action-wrapper.ex
Created April 28, 2019 12:54
Absinthe resolver action wrapper
def action_wrapped(fun) do
case fun.() do
{:ok, result} ->
{:ok, result}
{:error, changeset = %Changeset{}} ->
{
:error,
%{
message: "Changeset errors occurred",
@sultaniman
sultaniman / absinthe-resolver-with-standard-errors.ex
Last active April 28, 2019 12:52
Sample resolver with standard errors
defmodule IdpWeb.Schema.CityResolvers do
use IdpWeb.Schema.Errors
alias Idp.Geo.Cities
alias Idp.EctoHelpers
def create(_parent, city, _ctx) do
EctoHelpers.action_wrapped(fn ->
Cities.create_city(city)
end)
@sultaniman
sultaniman / standard-absinthe-errors.ex
Created April 28, 2019 12:43
Standard API errors
defmodule IdpWeb.Schema.Errors do
@moduledoc """
Defines common GraphQL error responses
"""
defmacro __using__(_) do
quote do
@permission_denied {
:error,
%{
message: "Permission denied",
@sultaniman
sultaniman / ecto-helpers.ex
Created April 28, 2019 12:39
Ecto helpers
defmodule Idp.EctoHelpers do
alias Ecto.Changeset
@doc """
Transform `%Ecto.Changeset{}` errors to a map
containing field name as a key on which validation
error happened and it's formatted message.
For example:
@sultaniman
sultaniman / common-changeset-error.ex
Created April 28, 2019 12:33
Common changeset error
{
:error,
%{
message: "Changeset errors occurred",
code: :changeset_errors,
errors: [
%{field: "error message"}
]
}
}