Ошибка сообщения Elixir marshal ISO 8583 с библиотекой Erlang

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

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" это было отправлено из моей функции. Я пытался изменить двойные кавычки на одинарные, но безуспешно. Есть ли другие предложения, что я должен делать?

1 ответ

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

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

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

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

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

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

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"), Эликсир называет "чарты" и вставляет одинарные кавычки ('foo').
  • То, что Эликсир называет "струнами" и помещает в двойные кавычки ("foo"), Эрланг называет "двоичные файлы" и вставляет двойные кавычки плюс угловые скобки (<<"foo">>).

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

Другие вопросы по тегам