Ошибка сообщения Elixir marshal ISO 8583 с библиотекой Erlang - PullRequest
0 голосов
/ 18 сентября 2018

Я новичок в elixir, и мне нужно создать клиент ISO 8583 с этим языком и инфраструктурой Phoenix.Я нашел для него библиотеку Erlang из потока stackoverflow здесь , успешно скомпилирован и последовал примеру в репозитории here , но получил ошибку при маршалинге сообщения.Вот мой код Elixir для маршалинга сообщения:

msg1 = :erl8583_message.new()
msg2 = :erl8583_message.set_mti("0800", msg1)
msg3 = :erl8583_message.set(3, "300000", msg2)
msg4 = :erl8583_message.set(24, "045", msg3)
msg5 = :erl8583_message.set(41, "11111111", msg4)
msg6 = :erl8583_message.set(42, "222222222222222", msg5)
msg7 = :erl8583_message.set(63, "This is a Test Message", msg6)
marshalled = :erl8583_marshaller_ascii.marshal(msg7)

Это просто версия эликсира из примера на репо.Это ошибка, которую я получил при запуске приложения:

[error] #PID<0.438.0> running TestlangIsoClientWeb.Endpoint (cowboy_protocol) terminated
Server: 127.0.0.1:4001 (http)
Request: POST /api/process
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in :erl8583_marshaller_ascii.marshal_data_element/2
        (erl8583) /home/muhammad/Workspace/testlang/testlang_iso_client/deps/erl8583/src/erl8583_marshaller_ascii.erl:168: :erl8583_marshaller_ascii.marshal_data_element({:n, :fixed, 4}, "0800")
        (erl8583) /home/muhammad/Workspace/testlang/testlang_iso_client/deps/erl8583/src/erl8583_marshaller.erl:108: :erl8583_marshaller.marshal/2
        (testlang_iso_client) lib/testlang_iso_client_web/controllers/my_controller.ex:61: TestlangIsoClientWeb.MyController.process/2
        (testlang_iso_client) lib/testlang_iso_client_web/controllers/my_controller.ex:1: TestlangIsoClientWeb.MyController.action/2
        (testlang_iso_client) lib/testlang_iso_client_web/controllers/my_controller.ex:1: TestlangIsoClientWeb.MyController.phoenix_controller_pipeline/2
        (testlang_iso_client) lib/testlang_iso_client_web/endpoint.ex:1: TestlangIsoClientWeb.Endpoint.instrument/4
        (phoenix) lib/phoenix/router.ex:278: Phoenix.Router.__call__/1
        (testlang_iso_client) lib/testlang_iso_client_web/endpoint.ex:1: TestlangIsoClientWeb.Endpoint.plug_builder_call/2
        (testlang_iso_client) lib/testlang_iso_client_web/endpoint.ex:1: TestlangIsoClientWeb.Endpoint.call/2
        (plug) lib/plug/adapters/cowboy/handler.ex:16: Plug.Adapters.Cowboy.Handler.upgrade/4
        (cowboy) /home/muhammad/Workspace/testlang/testlang_iso_client/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4

Есть что-то, что я пропустил, чтобы оно заработало?Любая помощь будет принята с благодарностью.

Обновлено

Я пытался изменить строковый параметр на charlist, но все равно получил ту же ошибку.Вот фрагмент кода:

def test(conn, _params) do
  IO.puts("Test")
  msg1 = :erl8583_message.new()
  msg2 = :erl8583_message.set_mti('0800', msg1)
  msg3 = :erl8583_message.set(3, '300000', msg2)
  msg4 = :erl8583_message.set(24, '045', msg3)
  msg5 = :erl8583_message.set(41, '11111111', msg4)
  msg6 = :erl8583_message.set(42, '222222222222222', msg5)
  msg7 = :erl8583_message.set(63, 'This is a Test Message', msg6)
  marshalled = :erl8583_marshaller_ascii.marshal(msg7)
  json(conn, %{status: "ok"})
end

Вот функция erl8583_marshaller.erl:108, упомянутая в трассировке стека:

marshal(Message, MarshalHandlers) ->
    OptionsRecord = parse_options(MarshalHandlers, #marshal_options{}),
    {Marshalled1, Message1} = init_marshalling(OptionsRecord, Message),
    MarshalledMti = encode_mti(OptionsRecord, Message1),  % --- Line 108
    Marshalled2 = <<Marshalled1/binary, MarshalledMti/binary>>,
    {MarshalledBitmap, Message2} = encode_bitmap(OptionsRecord, Message1),
    Marshalled3 = <<Marshalled2/binary, MarshalledBitmap/binary>>,
    MarshalledFields = encode_fields(OptionsRecord, Message2),
    Marshalled4 = <<Marshalled3/binary, MarshalledFields/binary>>,
    end_marshalling(OptionsRecord, Message2, Marshalled4).

А вот функция erl8583_marshaller_ascii.erl:168, упомянутая в трассировке стека:

%%
%% Local Functions
%%
marshal_data_element({n, llvar, Length}, FieldValue) when length(FieldValue) =< Length ->
    erl8583_convert:integer_to_string(length(FieldValue), 2) ++ FieldValue;

Я не понимаю, почему вызов этой функции не соответствовал параметрам {:n, :fixed, 4}, "0800", которые были отправлены из моей функции.Я пытался изменить двойные кавычки на одинарные, но безуспешно.Есть ли другие предложения, что мне делать?

Ответы [ 2 ]

0 голосов
/ 14 января 2019

в коде может быть ошибка.Вы можете сослаться на эту проблему здесь

есть одна библиотека эликсира, которая является относительно новой.

она называется ale8583 .

документация все еще выходит на этот, но выглядит очень многообещающе.

вы можете проверить это.

0 голосов
/ 18 сентября 2018

Попробуйте передать списки вместо строк:

msg1 = :erl8583_message.new()
msg2 = :erl8583_message.set_mti('0800', msg1)
msg3 = :erl8583_message.set(3, '300000', msg2)
msg4 = :erl8583_message.set(24, '045', msg3)
msg5 = :erl8583_message.set(41, '11111111', msg4)
msg6 = :erl8583_message.set(42, '222222222222222', msg5)
msg7 = :erl8583_message.set(63, 'This is a Test Message', msg6)
marshalled = :erl8583_marshaller_ascii.marshal(msg7)

Здесь есть вероятность путаницы:

  • То, что Эрланг называет "строками" и ставит двойные кавычки ("foo"), Elixir называет «charlists» и вставляет одинарные кавычки ('foo').
  • То, что Elixir называет «строками» и вставляет двойные кавычки ("foo"), Erlang называет «бинарными» и ставит двойныекавычки плюс угловые скобки (<<"foo">>).

Кажется, что библиотека erl8583 ожидает строки Erlang повсюду.

...