let say i have routes like follow
web routes:
http://localhost:4000/department/:id/show
http://localhost:4000/department/:dept_id/user/:user_id
api routes:
http://localhost:4000/api/v1/department/:id/show
http://localhost:4000/api/v1/department/:dept_id/user/:user_id
and my module plug looks like
def call(%Plug.Conn{ params: %{ "dept_id" => dept_id } } = conn, _params) do
logged_in_user = Guardian.Plug.current_resource(conn)
result = MemberRepo.findUserBelongsToDept(logged_in_user, dept_id)
case result do
{:ok, 1} ->
conn #user belongs to group continue
{:ok, 0} ->
IO.puts "#{conn}"
conn
|> put_status(404)
{:error, error}->
conn
end
On those routes which i mentioned above i was checking whether the user belongs to the department or not using above plug. if not it returns {:ok, 0}
i want to render 404.html for webpage and json response for api calls within the plug , how can i achieve this?
Easiest way is to call the error view render function with whatever code you want then halt() the pipeline. 
Probably more correct ways, but that would work.
How can i check its halted or not , currently inside the call/2 i am doing like follow
body = "oops not found"
conn
|> put_resp_content_type("application/json")
|> send_resp(404, body)
|> halt
You could write a controller test that looks something like the following
test "this thing halts", %{conn: conn} do
conn = get(conn, some_path(conn, :index)
assert conn.halted
end
this is the right answer 
def call(conn, _) do
case logics(...) do
:ok -> conn
:error ->
conn
|> Phoenix.Controller.render(MyApp.Web.ErrorView, :"404")
|> halt()
end
end
Passing an atom to Phoenix.Controller.render will handle the content negation and render the html/json/etc template.
when i am trying to pass halt in pipes like follow
conn
|> Phoenix.Controller.render(XXXX.Api.V1.ErrorView, :“404error”)
|> halt()
it continues to call another plug, why doesn’t it work, ?
Mistake from my side only, this code works now 
conn = conn
|> Phoenix.Controller.render(XXXX.Api.V1.ErrorView, :"404error")
|> halt()