Problem

Hello. I faced an error when a server returns an error contains Non Ascii message like this.

func (s *serv) F(context.Context, *empty.Empty) (*empty.Empty, error) {
        _, err := func()
	if err != nil {
		return nil, twirp.NewError(twirp.InvalidArgument,
                      "これはエラーです/這是一個錯誤") // Not ascii message
	}
}

When above server returns the error, the message is garbled as follows.

Error: ����������������
    at eval (twirp.js?27db:44)
twirp.js?27db:44 Uncaught (in promise) Error: ����������������
    at eval (twirp.js?27db:44)

Reason

Maybe this code is invalid. I recommend to use new TextDecoder("utf-8").decode

s = String.fromCharCode.apply(null, new Uint8Array(data));
String.fromCharCode.apply(null, new Uint8Array([123,34,99,111,100,101,34,58,34,105,110,118,97,108,105,100,95,97,114,103,117,109,101,110,116,34,44,34,109,115,103,34,58,34,-29,-127,-109,-29,-126,-116,-29,-127,-81,-29,-126,-88,-29,-125,-87,-29,-125,-68,-29,-127,-89,-29,-127,-103,47,-23,-128,-103,-26,-104,-81,-28,-72,-128,-27,-128,-117,-23,-116,-81,-24,-86,-92,34,125]));
"{"code":"invalid_argument","msg":"��������/�����誤"}"
new TextDecoder("utf-8").decode( new Uint8Array([123,34,99,111,100,101,34,58,34,105,110,118,97,108,105,100,95,97,114,103,117,109,101,110,116,34,44,34,109,115,103,34,58,34,-29,-127,-109,-29,-126,-116,-29,-127,-81,-29,-126,-88,-29,-125,-87,-29,-125,-68,-29,-127,-89,-29,-127,-103,47,-23,-128,-103,-26,-104,-81,-28,-72,-128,-27,-128,-117,-23,-116,-81,-24,-86,-92,34,125]));
"{"code":"invalid_argument","msg":"これはエラーです/這是一個錯誤"}"
Most sincerely.

Solve

Add const err = decodeURIComponent(escape(error));.

try {
  const payload: api.Req = {
    message: ""
  };
  const res: api.Req = await Service.ping(payload);
  // Add impl
} catch (err) {
  // --- Add code to this. ---
  const error = decodeURIComponent(escape(err));
  // -------------------------
  console.error(error);
  throw error;
}

Ref

PR