Text format parsing error in line 1 unexpected end of input stream

What can you do to pin down metrics-parsing related scrape errors in Prometheus?

What can you do to pin down metrics-parsing related scrape errors in Prometheus?

Not all scrape errors are due to network or HTTP issues. There’s also a variety of parsing errors that are possible including "INVALID" is not a valid start tokenstrconv.ParseFloat: parsing "...": invalid syntaxexpected timestamp or new record, got "MNAME" and expected label name, got "INVALID". There’s a number of common causes of these such as having hyphens or periods in metric names, numbers at the start of label or metric names, and missing the newline on the last line of the output.

While spotting these by hand is possible, there’s an easier way to figure out which line is the issue. promtool which comes with Prometheus has a subcommand to check metrics syntax. Let’s download it and try it out:

wget https://github.com/prometheus/prometheus/releases/download/v2.7.1/prometheus-2.7.1.linux-amd64.tar.gz
tar -xzf prometheus-*.tar.gz
cd prometheus-*
echo 'a.b 1' | ./promtool check metrics

Which will produce output like:

error while linting: text format parsing error in line 1: expected float as value, got ".b"

indicating that the period in the metric name is the issue.

If the trailing newline was missing it’d look like:

$ echo -n 'a 1' | ./promtool check metrics
error while linting: text format parsing error in line 1: unexpected end of input stream

Once you know what the problem is, you can fix the bug in the relevant server so that it produces valid Prometheus text output.

Beyond checking if metrics output can be parsed, this also acts as a linter. For example:

echo 'a 1' | ./promtool check metrics
a no help text

Usually you don’t use echo, but fetch the metrics via HTTP:

$ GET http://demo.robustperception.io:9100/metrics | ./promtool check metrics

The lack of output here indicates that all is well, and the exit code will also be 0.

Need help exposing metrics? Contact us.

Published by Brian Brazil in Posts

// Copyright 2014 The Prometheus Authors // Licensed under the Apache License, Version 2.0 (the «License»); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an «AS IS» BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package expfmt import ( «math» «strings» «testing» «github.com/golang/protobuf/proto» //nolint:staticcheck // Ignore SA1019. Need to keep deprecated package for compatibility. dto «github.com/prometheus/client_model/go» ) func testTextParse(t testing.TB) { var scenarios = []struct { in string out []*dto.MetricFamily }{ // 0: Empty lines as input. { in: ` `, out: []*dto.MetricFamily{}, }, // 1: Minimal case. { in: ` minimal_metric 1.234 another_metric -3e3 103948 # Even that: no_labels{} 3 # HELP line for non-existing metric will be ignored. `, out: []*dto.MetricFamily{ &dto.MetricFamily{ Name: proto.String(«minimal_metric»), Type: dto.MetricType_UNTYPED.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Untyped: &dto.Untyped{ Value: proto.Float64(1.234), }, }, }, }, &dto.MetricFamily{ Name: proto.String(«another_metric»), Type: dto.MetricType_UNTYPED.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Untyped: &dto.Untyped{ Value: proto.Float64(3e3), }, TimestampMs: proto.Int64(103948), }, }, }, &dto.MetricFamily{ Name: proto.String(«no_labels»), Type: dto.MetricType_UNTYPED.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Untyped: &dto.Untyped{ Value: proto.Float64(3), }, }, }, }, }, }, // 2: Counters & gauges, docstrings, various whitespace, escape sequences. { in: ` # A normal comment. # # TYPE name counter name{labelname=»val1″,basename=»basevalue»} NaN name {labelname=»val2″,basename=»base»v\alnue»} 0.23 1234567890 # HELP name two-linen doc str\ing # HELP name2 doc str»ing 2 # TYPE name2 gauge name2{labelname=»val2″ ,basename = «basevalue2» } +Inf 54321 name2{ labelname = «val1» , }-Inf `, out: []*dto.MetricFamily{ &dto.MetricFamily{ Name: proto.String(«name»), Help: proto.String(«two-linen doc str\ing»), Type: dto.MetricType_COUNTER.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«labelname»), Value: proto.String(«val1»), }, &dto.LabelPair{ Name: proto.String(«basename»), Value: proto.String(«basevalue»), }, }, Counter: &dto.Counter{ Value: proto.Float64(math.NaN()), }, }, &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«labelname»), Value: proto.String(«val2»), }, &dto.LabelPair{ Name: proto.String(«basename»), Value: proto.String(«base«v\alnue»), }, }, Counter: &dto.Counter{ Value: proto.Float64(.23), }, TimestampMs: proto.Int64(1234567890), }, }, }, &dto.MetricFamily{ Name: proto.String(«name2»), Help: proto.String(«doc str«ing 2″), Type: dto.MetricType_GAUGE.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«labelname»), Value: proto.String(«val2»), }, &dto.LabelPair{ Name: proto.String(«basename»), Value: proto.String(«basevalue2»), }, }, Gauge: &dto.Gauge{ Value: proto.Float64(math.Inf(+1)), }, TimestampMs: proto.Int64(54321), }, &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«labelname»), Value: proto.String(«val1»), }, }, Gauge: &dto.Gauge{ Value: proto.Float64(math.Inf(1)), }, }, }, }, }, }, // 3: The evil summary, mixed with other types and funny comments. { in: ` # TYPE my_summary summary my_summary{n1=»val1″,quantile=»0.5″} 110 decoy -1 -2 my_summary{n1=»val1″,quantile=»0.9″} 140 1 my_summary_count{n1=»val1″} 42 # Latest timestamp wins in case of a summary. my_summary_sum{n1=»val1″} 4711 2 fake_sum{n1=»val1″} 2001 # TYPE another_summary summary another_summary_count{n2=»val2″,n1=»val1″} 20 my_summary_count{n2=»val2″,n1=»val1″} 5 5 another_summary{n1=»val1″,n2=»val2″,quantile=».3″} -1.2 my_summary_sum{n1=»val2″} 08 15 my_summary{n1=»val3″, quantile=»0.2″} 4711 my_summary{n1=»val1″,n2=»val2″,quantile=»-12.34″,} NaN # some # funny comments # HELP # HELP # HELP my_summary # HELP my_summary `, out: []*dto.MetricFamily{ &dto.MetricFamily{ Name: proto.String(«fake_sum»), Type: dto.MetricType_UNTYPED.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«n1»), Value: proto.String(«val1»), }, }, Untyped: &dto.Untyped{ Value: proto.Float64(2001), }, }, }, }, &dto.MetricFamily{ Name: proto.String(«decoy»), Type: dto.MetricType_UNTYPED.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Untyped: &dto.Untyped{ Value: proto.Float64(1), }, TimestampMs: proto.Int64(2), }, }, }, &dto.MetricFamily{ Name: proto.String(«my_summary»), Type: dto.MetricType_SUMMARY.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«n1»), Value: proto.String(«val1»), }, }, Summary: &dto.Summary{ SampleCount: proto.Uint64(42), SampleSum: proto.Float64(4711), Quantile: []*dto.Quantile{ &dto.Quantile{ Quantile: proto.Float64(0.5), Value: proto.Float64(110), }, &dto.Quantile{ Quantile: proto.Float64(0.9), Value: proto.Float64(140), }, }, }, TimestampMs: proto.Int64(2), }, &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«n2»), Value: proto.String(«val2»), }, &dto.LabelPair{ Name: proto.String(«n1»), Value: proto.String(«val1»), }, }, Summary: &dto.Summary{ SampleCount: proto.Uint64(5), Quantile: []*dto.Quantile{ &dto.Quantile{ Quantile: proto.Float64(12.34), Value: proto.Float64(math.NaN()), }, }, }, TimestampMs: proto.Int64(5), }, &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«n1»), Value: proto.String(«val2»), }, }, Summary: &dto.Summary{ SampleSum: proto.Float64(8), }, TimestampMs: proto.Int64(15), }, &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«n1»), Value: proto.String(«val3»), }, }, Summary: &dto.Summary{ Quantile: []*dto.Quantile{ &dto.Quantile{ Quantile: proto.Float64(0.2), Value: proto.Float64(4711), }, }, }, }, }, }, &dto.MetricFamily{ Name: proto.String(«another_summary»), Type: dto.MetricType_SUMMARY.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Label: []*dto.LabelPair{ &dto.LabelPair{ Name: proto.String(«n2»), Value: proto.String(«val2»), }, &dto.LabelPair{ Name: proto.String(«n1»), Value: proto.String(«val1»), }, }, Summary: &dto.Summary{ SampleCount: proto.Uint64(20), Quantile: []*dto.Quantile{ &dto.Quantile{ Quantile: proto.Float64(0.3), Value: proto.Float64(1.2), }, }, }, }, }, }, }, }, // 4: The histogram. { in: ` # HELP request_duration_microseconds The response latency. # TYPE request_duration_microseconds histogram request_duration_microseconds_bucket{le=»100″} 123 request_duration_microseconds_bucket{le=»120″} 412 request_duration_microseconds_bucket{le=»144″} 592 request_duration_microseconds_bucket{le=»172.8″} 1524 request_duration_microseconds_bucket{le=»+Inf»} 2693 request_duration_microseconds_sum 1.7560473e+06 request_duration_microseconds_count 2693 `, out: []*dto.MetricFamily{ { Name: proto.String(«request_duration_microseconds»), Help: proto.String(«The response latency.»), Type: dto.MetricType_HISTOGRAM.Enum(), Metric: []*dto.Metric{ &dto.Metric{ Histogram: &dto.Histogram{ SampleCount: proto.Uint64(2693), SampleSum: proto.Float64(1756047.3), Bucket: []*dto.Bucket{ &dto.Bucket{ UpperBound: proto.Float64(100), CumulativeCount: proto.Uint64(123), }, &dto.Bucket{ UpperBound: proto.Float64(120), CumulativeCount: proto.Uint64(412), }, &dto.Bucket{ UpperBound: proto.Float64(144), CumulativeCount: proto.Uint64(592), }, &dto.Bucket{ UpperBound: proto.Float64(172.8), CumulativeCount: proto.Uint64(1524), }, &dto.Bucket{ UpperBound: proto.Float64(math.Inf(+1)), CumulativeCount: proto.Uint64(2693), }, }, }, }, }, }, }, }, } for i, scenario := range scenarios { out, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in)) if err != nil { t.Errorf(«%d. error: %s», i, err) continue } if expected, got := len(scenario.out), len(out); expected != got { t.Errorf( «%d. expected %d MetricFamilies, got %d», i, expected, got, ) } for _, expected := range scenario.out { got, ok := out[expected.GetName()] if !ok { t.Errorf( «%d. expected MetricFamily %q, found none», i, expected.GetName(), ) continue } if expected.String() != got.String() { t.Errorf( «%d. expected MetricFamily %s, got %s», i, expected, got, ) } } } } func TestTextParse(t *testing.T) { testTextParse(t) } func BenchmarkTextParse(b *testing.B) { for i := 0; i < b.N; i++ { testTextParse(b) } } func testTextParseError(t testing.TB) { var scenarios = []struct { in string err string }{ // 0: No new-line at end of input. { in: ` bla 3.14 blubber 42`, err: «text format parsing error in line 3: unexpected end of input stream», }, // 1: Invalid escape sequence in label value. { in: `metric{label=»t»} 3.14`, err: «text format parsing error in line 1: invalid escape sequence», }, // 2: Newline in label value. { in: ` metric{label=»new line»} 3.14 `, err: `text format parsing error in line 2: label value «new» contains unescaped new-line`, }, // 3: { in: `metric{@=»bla»} 3.14`, err: «text format parsing error in line 1: invalid label name for metric», }, // 4: { in: `metric{__name__=»bla»} 3.14`, err: `text format parsing error in line 1: label name «__name__» is reserved`, }, // 5: { in: `metric{label+=»bla»} 3.14`, err: «text format parsing error in line 1: expected ‘=’ after label name», }, // 6: { in: `metric{label=bla} 3.14`, err: «text format parsing error in line 1: expected ‘«‘ at start of label value», }, // 7: { in: ` # TYPE metric summary metric{quantile=»bla»} 3.14 `, err: «text format parsing error in line 3: expected float as value for ‘quantile’ label», }, // 8: { in: `metric{label=»bla»+} 3.14`, err: «text format parsing error in line 1: unexpected end of label value», }, // 9: { in: `metric{label=»bla»} 3.14 2.72 `, err: «text format parsing error in line 1: expected integer as timestamp», }, // 10: { in: `metric{label=»bla»} 3.14 2 3 `, err: «text format parsing error in line 1: spurious string after timestamp», }, // 11: { in: `metric{label=»bla»} blubb `, err: «text format parsing error in line 1: expected float as value», }, // 12: { in: ` # HELP metric one # HELP metric two `, err: «text format parsing error in line 3: second HELP line for metric name», }, // 13: { in: ` # TYPE metric counter # TYPE metric untyped `, err: `text format parsing error in line 3: second TYPE line for metric name «metric», or TYPE reported after samples`, }, // 14: { in: ` metric 4.12 # TYPE metric counter `, err: `text format parsing error in line 3: second TYPE line for metric name «metric», or TYPE reported after samples`, }, // 14: { in: ` # TYPE metric bla `, err: «text format parsing error in line 2: unknown metric type», }, // 15: { in: ` # TYPE met-ric `, err: «text format parsing error in line 2: invalid metric name in comment», }, // 16: { in: `@invalidmetric{label=»bla»} 3.14 2`, err: «text format parsing error in line 1: invalid metric name», }, // 17: { in: `{label=»bla»} 3.14 2`, err: «text format parsing error in line 1: invalid metric name», }, // 18: { in: ` # TYPE metric histogram metric_bucket{le=»bla»} 3.14 `, err: «text format parsing error in line 3: expected float as value for ‘le’ label», }, // 19: Invalid UTF-8 in label value. { in: «metric{l=«xbd«} 3.14n«, err: «text format parsing error in line 1: invalid label value «\xbd««, }, // 20: Go 1.13 sometimes allows underscores in numbers. { in: «foo 1_2n«, err: «text format parsing error in line 1: expected float as value», }, // 21: Go 1.13 supports hex floating point. { in: «foo 0x1p-3n«, err: «text format parsing error in line 1: expected float as value», }, // 22: Check for various other literals variants, just in case. { in: «foo 0x1P-3n«, err: «text format parsing error in line 1: expected float as value», }, // 23: { in: «foo 0B1n«, err: «text format parsing error in line 1: expected float as value», }, // 24: { in: «foo 0O1n«, err: «text format parsing error in line 1: expected float as value», }, // 25: { in: «foo 0X1n«, err: «text format parsing error in line 1: expected float as value», }, // 26: { in: «foo 0x1n«, err: «text format parsing error in line 1: expected float as value», }, // 27: { in: «foo 0b1n«, err: «text format parsing error in line 1: expected float as value», }, // 28: { in: «foo 0o1n«, err: «text format parsing error in line 1: expected float as value», }, // 29: { in: «foo 0x1n«, err: «text format parsing error in line 1: expected float as value», }, // 30: { in: «foo 0x1n«, err: «text format parsing error in line 1: expected float as value», }, // 31: Check histogram label. { in: ` # TYPE metric histogram metric_bucket{le=»0x1p-3″} 3.14 `, err: «text format parsing error in line 3: expected float as value for ‘le’ label», }, // 32: Check quantile label. { in: ` # TYPE metric summary metric{quantile=»0x1p-3″} 3.14 `, err: «text format parsing error in line 3: expected float as value for ‘quantile’ label», }, // 33: Check duplicate label. { in: `metric{label=»bla»,label=»bla»} 3.14`, err: «text format parsing error in line 1: duplicate label names for metric», }, } for i, scenario := range scenarios { _, err := parser.TextToMetricFamilies(strings.NewReader(scenario.in)) if err == nil { t.Errorf(«%d. expected error, got nil», i) continue } if expected, got := scenario.err, err.Error(); strings.Index(got, expected) != 0 { t.Errorf( «%d. expected error starting with %q, got %q», i, expected, got, ) } } } func TestTextParseError(t *testing.T) { testTextParseError(t) } func BenchmarkParseError(b *testing.B) { for i := 0; i < b.N; i++ { testTextParseError(b) } }

Я пытаюсь отправить метрики на pushgateway из окон. Но я получаю следующую ошибку:

ошибка синтаксического анализа текстового формата в строке 1: неверное имя метрики

Это команда, которую я запускаю из консоли:

echo "some_metric 10" | curl --data-binary @ - http: // localhost: 9091 / metrics / job / some_job

Как я могу отправить свои показатели из консоли Windows?

Благодарность

2 ответа

Лучший ответ

Я столкнулся с той же проблемой, я думаю, это как-то связано с запуском в Windows. Вы можете попробовать сделать это с помощью скрипта powershell, это сработало для меня:

Invoke-WebRequest -Uri http://localhost:9091/metrics/job/some_job -Method POST


1

victooor
28 Сен 2021 в 16:37

У меня была еще одна ошибка при запуске команд из Windows Powershell с использованием как curl.exe, так и Invoke-WebRequest:

curl.exe -X PUT -d "some_metric 3.14" http://localhost:9091/metrics/job/some_job

echo "some_metric 10" | Invoke-WebRequest -Uri http://localhost:9091/metrics/job/some_job -Method POST

Вот сообщение об ошибке:

text format parsing error in line 1: unexpected end of input stream

Я обнаружил, что он не передает перевод строки, который необходим в соответствии с официальным документом. :

Обратите внимание, что в текстовом протоколе каждая строка должна заканчиваться символом перевода строки (он же ‘LF’ или ‘n’). Завершение строки другими способами, например. с ‘CR’, также известным как ‘r’, ‘CRLF’, также известным как ‘rn’, или просто в конце пакета приведет к ошибке протокола.

Поэтому я поставил перевод строки в конце данных, и теперь это работает:

curl.exe -X PUT -d "some_metric 3.14
>> " http://localhost:9091/metrics/job/some_job

В качестве альтернативы я также могу запустить команду Invoke-WebRequest:

echo "some_metric 20
>> " | Invoke-WebRequest -Uri http://localhost:9091/metrics/job/some_job -Method POST


0

Saeed Mohtasham
28 Июн 2022 в 18:06

Ситуация: вы пишете скрипт, в котором объявляете новые функции или используете уже встроенные. Вы уверены, что всё правильно, потому что делали так сотни раз в других проектах, но при запуске кода появляется такая ошибка:

❌ Uncaught SyntaxError: Unexpected end of input

Что это значит: браузер ждёт от вас или от кода продолжения ввода параметров или новых значений, но не находит их и падает с ошибкой.

Когда встречается: чаще всего это значит, что вы где-то потеряли закрывающие скобки. Вторая ситуация, более редкая — вы обрабатываете JSON-запрос и вам просто не приходят нужные данные (хотя должны бы). О том, что такое JSON-запросы и ответы, будет в отдельной статье — тема слишком большая и интересная для короткого ответа. Сейчас остановимся на первом варианте.

Что делать с ошибкой Uncaught SyntaxError: Unexpected end of input

Чтобы отловить и исправить эту ошибку, вам нужно посчитать и сравнить количество открытых и закрытых скобок в программе — как круглых (), так и фигурных {}. Скорее всего, вам не хватает и того, и другого (и точки с запятой после них).

Проще всего такую ошибку найти простым форматированием кода: когда все вложенные команды и параметры сдвигаются вправо табуляцией или пробелами. В этом случае легко найти разрыв в получившейся лесенке кода и добавить туда нужные скобки. Смотрите сами:

$(function () {
  $("#mewlyDiagnosed").hover(function () {
    $("#mewlyDiagnosed").animate({ 'height': '237px', 'top': "-75px" });
  }, function () {
    $("#mewlyDiagnosed").animate({ 'height': '162px', 'top': "0px" });
  });

Может показаться, что всё в порядке, но вот как выглядит этот код после форматирования:

$(function () {
  $("#mewlyDiagnosed").hover(function () {
    $("#mewlyDiagnosed").animate({ 'height': '237px', 'top': "-75px" });
  }, function () {
    $("#mewlyDiagnosed").animate({ 'height': '162px', 'top': "0px" });
  });

Сразу видно, что в конце скрипта не хватает строки с )}; — если их не поставить, браузер будет ждать продолжения ввода параметров вызова функции, не дождётся их и выдаст ошибку Uncaught SyntaxError: Unexpected end of input

Попробуйте сами. Найдите ошибку в этом коде:

$(function() {

  // Script to select all checkboxes

  $state.on('change', function(ev) {

    var $chcks = $("#example tbody input[type='checkbox']");

    if($state.is(':checked')) {

      $chcks.prop('checked', true).trigger('change');

    }else {

      $chcks.prop('checked', false).trigger('change');

  });

“SyntaxError: Unexpected end of input” problem often occurs when we miss a closing parenthesis, bracket, or quote. Check out our instructions below to find the best solution that works for you.

  • Find more about JS Type of Errors

What causes the error “SyntaxError: Unexpected end of input”?

Reproduce the “SyntaxError: Unexpected end of input” in JavaScript

Let’s take a look at one example:

function hello() {
  console.log('Welcome to LearnShareIt.com');

hello();

In this example, we can easily spot that a parenthesis is missing. Therefore, you will receive the Unexpected end of input error. To make it easier for you to understand, this simply means that the computer is telling you: “Hey man, you opened the parenthesis but forgot to close it.”

Here is another example: 

const obj = JSON.parse('');

When you are trying to parse an empty JSON string with JSON.parse(), it might also lead to getting the Unexpected end of input error

Solution 1: Add the missing parenthesis, bracket or quote!

The easiest way to fix this problem is to just add the closing parenthesis, bracket, or quote. 

function hello() {
  console.log('Welcome to LearnShareIt.com');
} 

hello();

Output:

Welcome to LearnShareIt.com

The parenthesis works like a door. If you open it, then you have to close it so that your program will work properly.

Solution 2: Use extensions/tools

We can use solution 1 without any problems for small projects or exercises. But for real-world larger projects, it is not always easy to do so. Let’s take a look at an example: 

const array = [1, 2, 3, 4, 5];

function even(){
  for (let i=0; i<5; i++) {
    if (array[i]%2===0){
      console.log(array[i]);
  }
}

even();

As you can see, the errors are less obvious in this example. Since then, we can use some online JavaScript Syntax Validators found easily on the Internet to help us check the syntax of our code.

Fixed code:

const array = [1, 2, 3, 4, 5];

function even(){
  for (let i=0; i<5; i++) {
    if (array[i]%2===0){
      console.log(array[i]);
    }
  }
}

even();

Output:

2
4

Solution 3: Avoid parsing empty JSON string

Make sure that your string is not empty before parsing.

Summary

The “SyntaxError: Unexpected end of input” error in JavaScript can be caused by various reasons, but the most common one is that we forget a closing parenthesis, bracket, or quote. To make it easier to handle large programs or projects, we can use a JavaScript validator to double-check the syntax.

Maybe you are interested in similar errors:

  • ReferenceError: document is not defined
  • Unexpected token u in JSON at position 0
  • Uncaught SyntaxError: Unexpected token
  • Unexpected token o in json at position 1 error in js

Hello. My name is Khanh Hai Ngo. I graduated in Information Technology at VinUni. My advanced programming languages include C, C++, Python, Java, JavaScript, TypeScript, and R, which I would like to share with you. You will benefit from my content.


Name of the university: VinUni
Major: EE
Programming Languages: C, C++, Python, Java, JavaScript, TypeScript, R

Code formatting. Tabs or spaces, semi-colons or no semi-colons. It is a pretty controversial subject to many but it is quite important in some instances. If you are on a team, having a cohesive code format helps code readability among your peers. Even if you work alone, one big benefit of having a good sense of code formatting is to avoid syntactical errors.

JavaScript is pretty open when it comes to code format. There is a wide range of different ways to format your codebase in this language. What can happen if you don’t do it? Well, an example of a simple error that is often caused by code formatting issues is the Unexpected end of input error. How does it work?

The Problem

When JavaScript code is run it uses just in time compilation (JIT) to turn your code into something the computer can do. When this happens your code is read and certain things are expected about the code, for example having matching parentheses. If you received the Unexpected end of input error, odds are you are missing a closing curly brace } so the error is basically saying “you opened the curly brace but the code ended before it was closed”.

Here’s an example:

const writeHelloWorld = () => { console.log('hello world') writeHelloWorld();

Code language: JavaScript (javascript)

As you can see, the code is clearly missing a ending curly brace at the end of the arrow function which causes the error. So how does the code formatting mentioned earlier fit into this? Let’s look at a more real-world example:

const items = ['one', 'two', 'three']; function parseItems() { for (let i = 0; i < items.length; i++) { if (items[i]) { console.log(items[i]) } } parseItems();

Code language: JavaScript (javascript)

In this example, it is a little less clear where the error is. The indentation is not very consistent so you might not notice that the if statement is actually missing a curly brace after which causes the error.

The Solution

Fortunately this is pretty simple to fix — you can just add your missing curly brace. In the above example:

const items = ["one", "two", "three"]; function parseItems() { for (let i = 0; i < items.length; i++) { if (items[i]) { console.log(items[i]); // indented this line over } // added this curly brace } } parseItems();

Code language: JavaScript (javascript)

It can definitely be challenging to find a missing curly brace. Depending on your code editor of choice, you may be able to configure different colors for each pair of curly brace so it is easier to see which ones match and which ones don’t.

Another approach is to try and avoid these errors from the start. Using formatting tools such as Prettier or linting tools like ESLint can help a lot, at least in my experience.

Unexpected end of JSON input

There’s a chance that you received a similarly named but slightly different error: Unexpected end of JSON input. Rather than simply a missing curly brace, this error often occurs when you are trying to parse a JSON string that is itself missing a curly brace. Here’s an example:

const parseJson = (input) => JSON.parse(input); const validJson = JSON.stringify({ hello: "world" }); const invalidJson = "{"; console.log(parseJson(validJson)); // prints out a valid object console.log(parseJson(invalidJson)); // throws an error

Code language: JavaScript (javascript)

This can be simply fixed by ensuring the string you are parsing is valid JSON if you have control over that string. If you don’t, you can wrap the whole thing in a try / catch to be safe. Using the previous example:

const parseJson = (input) => { try { return JSON.parse(input); } catch (error) { return "error parsing input"; } };

Code language: JavaScript (javascript)

If you add this to the parseJson function, you can now handle invalid JSON strings rather than getting an unexpected runtime error.

Conclusion

Hopefully this helps you see how useful good code formatting can be in your code, whether you work with a team or alone. Let us know if you have any other reasons why formatting can be so useful or how you do it in your own code setup. Thanks for reading!

Понравилась статья? Поделить с друзьями:
  • Texmod ошибка d oh
  • Teso ошибка 301
  • Teso ошибка 210 что делать
  • Texmod d oh как исправить
  • Teso ошибка 210 не удалось загрузить манифест обновления