Backendless encountered an error while handling an API request

Hi,
I got the error message below when trying to Save and deploy some Cloud Code. I can’t see why the small changes I’ve done is encountering an error (but maybe I’m missing something). However, the error message indicates that this might not be my code but something more generic in Backendless that you guys will look into?

Just trying to understand if I should try and find an error or sit tight and wait for some response from you guys?


Backendless encountered an error while handling an API request.

We logged this error with ID 724A5FF8-DD51-43B4-AA8D-0F269F4D4BF0 and will be investigating the issue.


/Dennis

Hello @Dennis_Liljedahl

Could you share full error message?

Backendless encountered an error while handling the request. An internal trouble ticket with ID bl-server:5FAFD80F-DAAF-4345-907E-06B250895DB7 has been created and we will be investigating the issue.
Cannot invoke “com.fasterxml.jackson.databind.JsonNode.asText()” because the return value of “com.fasterxml.jackson.databind.JsonNode.get(String)” is null
java.lang.NullPointerException: Cannot invoke “com.fasterxml.jackson.databind.JsonNode.asText()” because the return value of “com.fasterxml.jackson.databind.JsonNode.get(String)” is null
at com.backendless.cloudcode.timers.TimerHelper.convertToTimer(TimerHelper.java:38)
at com.backendless.management.servercode.service.CustomServiceManagement.lambda$checkLimits$22(CustomServiceManagement.java:584)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
at java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:258)
at java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:248)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.count(ReferencePipeline.java:709)
at com.backendless.management.servercode.service.CustomServiceManagement.checkLimits(CustomServiceManagement.java:587)
at com.backendless.management.servercode.service.CustomServiceManagement.parseBusinessLogic(CustomServiceManagement.java:435)
at com.backendless.monitoring.PerformanceMonitoring.invoke(PerformanceMonitoring.java:32)
at controllers.console.ServerCode.lambda$deployDraft$1(ServerCode.java:173)
at com.backendless.async.BackendlessExecutorService.lambda$submit$0(BackendlessExecutorService.java:82)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:840)


{
“message”: “Backendless encountered an error while handling the request. An internal trouble ticket with ID bl-server:5FAFD80F-DAAF-4345-907E-06B250895DB7 has been created and we will be investigating the issue.\nCannot invoke "com.fasterxml.jackson.databind.JsonNode.asText()" because the return value of "com.fasterxml.jackson.databind.JsonNode.get(String)" is null\njava.lang.NullPointerException: Cannot invoke "com.fasterxml.jackson.databind.JsonNode.asText()" because the return value of "com.fasterxml.jackson.databind.JsonNode.get(String)" is null\n\tat com.backendless.cloudcode.timers.TimerHelper.convertToTimer(TimerHelper.java:38)\n\tat com.backendless.management.servercode.service.CustomServiceManagement.lambda$checkLimits$22(CustomServiceManagement.java:584)\n\tat java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)\n\tat java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707)\n\tat java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)\n\tat java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)\n\tat java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)\n\tat java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:258)\n\tat java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:248)\n\tat java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)\n\tat java.base/java.util.stream.ReferencePipeline.count(ReferencePipeline.java:709)\n\tat com.backendless.management.servercode.service.CustomServiceManagement.checkLimits(CustomServiceManagement.java:587)\n\tat com.backendless.management.servercode.service.CustomServiceManagement.parseBusinessLogic(CustomServiceManagement.java:435)\n\tat com.backendless.monitoring.PerformanceMonitoring.invoke(PerformanceMonitoring.java:32)\n\tat controllers.console.ServerCode.lambda$deployDraft$1(ServerCode.java:173)\n\tat com.backendless.async.BackendlessExecutorService.lambda$submit$0(BackendlessExecutorService.java:82)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)\n\tat java.base/java.lang.Thread.run(Thread.java:840)\n”,
“status”: 500,
“headers”: {
“access-control-allow-methods”: “POST, GET, OPTIONS, PUT, DELETE, PATCH”,
“access-control-allow-origin”: “https://eu-develop.backendless.com”,
“connection”: “keep-alive”,
“content-length”: “2283”,
“content-type”: “text/plain; charset=UTF-8”,
“date”: “Fri, 25 Oct 2024 10:01:30 GMT”,
“server”: “nginx”,
“strict-transport-security”: “max-age=31536000; preload”,
“x-powered-by”: “Express”
},
“body”: “Backendless encountered an error while handling the request. An internal trouble ticket with ID bl-server:5FAFD80F-DAAF-4345-907E-06B250895DB7 has been created and we will be investigating the issue.\nCannot invoke "com.fasterxml.jackson.databind.JsonNode.asText()" because the return value of "com.fasterxml.jackson.databind.JsonNode.get(String)" is null\njava.lang.NullPointerException: Cannot invoke "com.fasterxml.jackson.databind.JsonNode.asText()" because the return value of "com.fasterxml.jackson.databind.JsonNode.get(String)" is null\n\tat com.backendless.cloudcode.timers.TimerHelper.convertToTimer(TimerHelper.java:38)\n\tat com.backendless.management.servercode.service.CustomServiceManagement.lambda$checkLimits$22(CustomServiceManagement.java:584)\n\tat java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)\n\tat java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1707)\n\tat java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)\n\tat java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)\n\tat java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)\n\tat java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:258)\n\tat java.base/java.util.stream.ReduceOps$5.evaluateSequential(ReduceOps.java:248)\n\tat java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)\n\tat java.base/java.util.stream.ReferencePipeline.count(ReferencePipeline.java:709)\n\tat com.backendless.management.servercode.service.CustomServiceManagement.checkLimits(CustomServiceManagement.java:587)\n\tat com.backendless.management.servercode.service.CustomServiceManagement.parseBusinessLogic(CustomServiceManagement.java:435)\n\tat com.backendless.monitoring.PerformanceMonitoring.invoke(PerformanceMonitoring.java:32)\n\tat controllers.console.ServerCode.lambda$deployDraft$1(ServerCode.java:173)\n\tat com.backendless.async.BackendlessExecutorService.lambda$submit$0(BackendlessExecutorService.java:82)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)\n\tat java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)\n\tat java.base/java.lang.Thread.run(Thread.java:840)\n”
}

Without changes model deployed successfully?

If so, could you share the changes? Send a part of code without and with changes.

This is the new code:

        // Beräkna foodRate
        const foodBonus = record.hasFoodStructure ? record.foodStructureBonus : 0;
        if (record.popValue >= record.popLimit) {
            record.popValue = record.popLimit;
        } else {
            record.foodRate = foodBonus + (record.foodSpeed * (1 - (record.popValue / record.popLimit)));
        }
        
        // Beräkna popValue
        record.popValue *= (1 + record.foodRate);

I don’t have the old code saved, so can’t show that. But the formulas was different and I didn’t have the if-else. However the changes seems to be saved, but not deployed.

We are talks about deploying JS API service(Data Fetch Service) to app with ID: 2D65B412-F4C2-4703-9D74-55DD4785495A right?

Is it possible to share full service? Secure id’s/keys must be removed before sharing if they exists.

Yes, that’s the one. Full code below.

// FUNKTION FÖR ATT HÄMTA, KONTROLLERA OCH UPPDATERA lastRunDate och batch
async function manageDateBatch() {
  console.log("=== BÖRJAR HÄMTA OCH KONTROLLERA DATUM OCH BATCH ===");

  const today = new Date().toDateString();
  console.log("Dagens datum: ", today);

  const query = Backendless.DataQueryBuilder.create().setPageSize(1);
  console.log("Query skapad för ResourceUpdateStatus: ", query);

  try {
    const records = await Backendless.Data.of("ResourceUpdateStatus").find(query);

    if (records.length > 0) {
      const record = records[0];
      console.log("Körningsdatum hämtat: ", record.lastRunDate, "| Senast bearbetad batch: ", record.lastProcessedBatch);

      // Kontrollera om det är ett nytt dygn
      if (!record.lastRunDate || record.lastRunDate !== today) {
        console.log("Det är ett nytt dygn, uppdaterar lastRunDate till idag och sätter batch till 0.");

        // Uppdatera lastRunDate och sätt batch till 0
        record.lastRunDate = today;
        record.lastProcessedBatch = 0;

        await Backendless.Data.of("ResourceUpdateStatus").save(record);
        console.log("Körningsdatum och batch uppdaterat till idag och batch 0.");
        return { shouldUpdate: true, currentBatch: 0 };
      } else {
        // Om det är samma dag, fortsätt med nästa batch
        const nextBatch = record.lastProcessedBatch + 1;
        console.log("Inleder bearbetning för batch: ", nextBatch);

        record.lastProcessedBatch = nextBatch;
        await Backendless.Data.of("ResourceUpdateStatus").save(record);
        console.log("Batch ", nextBatch, " bearbetad och uppdaterad.");
        return { shouldUpdate: true, currentBatch: nextBatch };
      }
    } else {
      console.error("Ingen post hittades i ResourceUpdateStatus.");
      return { shouldUpdate: false };
    }
  } catch (error) {
    console.error("Fel vid hämtning från ResourceUpdateStatus: ", error.message);
    return { shouldUpdate: false };
  }
}

// KLASS FÖR LOGIK OCH BERÄKNINGAR
class DataFetchService {
  constructor() {}

  // METOD FÖR ATT HÄMTA OCH UPPDATERA DATA
  async fetchData() {
    // Kolla om vi ska köra Realms-uppdateringen
    const { shouldUpdate, currentBatch } = await manageDateBatch();
    if (shouldUpdate) {
      console.log("Det är ett nytt dygn eller batch. Uppdaterar Realms-tabellen...");

      // Uppdatera Realms-tabellen för angiven batch
      const BATCH_SIZE = 10;
      const startTime = Date.now();
      const realmsQuery = Backendless.DataQueryBuilder.create()
      .setWhereClause("location IS NOT NULL AND location != ''")
      .setOffset(currentBatch * BATCH_SIZE)
      .setPageSize(BATCH_SIZE)
      .addProperty("objectId")
      .addProperty("popValue")
      .addProperty("foodRate")
      .addProperty("hasFoodStructure")
      .addProperty("goldValue")
      .addProperty("hasGoldStructure")
      .addProperty("RealmLevels[realmsRelation].popLimit")
      .addProperty("RealmLevels[realmsRelation].foodStructureBonus")
      .addProperty("RealmLevels[realmsRelation].foodSpeed")
      .addProperty("RealmLevels[realmsRelation].goldStructureBonus")
      .addProperty("RealmLevels[realmsRelation].goldSpeed");
      
      
      try {
        const records = await Backendless.Data.of("Realms").find(realmsQuery);
        console.log(`Antal poster som hämtades: ${records.length}`);
        if (records.length === 0) {
          console.log("Inga fler poster hittades.");
          return;
        }
      
      for (const record of records) {

        console.log(`Initial goldValue: ${record.goldValue}`);
        console.log(`Initial popLimit: ${record.popLimit}`);
        console.log(`Initial goldStructureBonus: ${record.goldStructureBonus}`);
        console.log(`Initial goldSpeed: ${record.goldSpeed}`);
        
        // Beräkna goldValue
        const goldBonus = record.hasGoldStructure ? record.goldStructureBonus : 0;
        console.log(`goldSpeed: ${record.goldSpeed}, goldBonus: ${goldBonus}, popValue: ${record.popValue}`);
        record.goldValue += (record.goldSpeed + goldBonus) * record.popValue;
        console.log(`Uppdaterat goldValue: ${record.goldValue}`);
        
        // Beräkna foodRate
        const foodBonus = record.hasFoodStructure ? record.foodStructureBonus : 0;
        if (record.popValue >= record.popLimit) {
            record.popValue = record.popLimit;
        } else {
            record.foodRate = foodBonus + (record.foodSpeed * (1 - (record.popValue / record.popLimit)));
        }
        
        // Beräkna popValue
        record.popValue *= (1 + record.foodRate);
    
        // Spara tillbaka uppdaterade poster till databasen
        await Backendless.Data.of("Realms").save(record);
      }



        const endTime = Date.now();
        const duration = endTime - startTime;
        console.log(`Tiden för att bearbeta batch ${currentBatch} Realms: ${duration} ms.`);
      } catch (error) {
        console.error("Fel vid hämtning eller uppdatering av poster: ", error.message);
      }
    } else {
      console.log("Ingen uppdatering av Realms-tabellen behövs idag.");
    }
  }
}

// Registrera API-tjänsten i Backendless
Backendless.ServerCode.addService(DataFetchService);

I have deployed the code that you provide into your app directly and everything works fine.

Try the next thing:

  1. Check if there are major differences with a service that I deploy temp_service - Google Drive
  2. Remove node_modules if they exist, and install them again if needed
  3. Check if there are no unneeded files in the service directory
  4. Compare codranner.json and package.json with those that I provide.

I’m confused, maybe because I’m kinda new to programming. But I’m not sure what you want me to do with the Google Drive files.

I tried to deploy the Cloud Code file again but still got the same error. And now when trying to run the Timer that starts the Cloud Code file, the timer UI says that the timer was run, but it doesn’t seem to do anything. The data in my table isn’t updated and I see nothing in the Real-time logging.

Hello @Dennis_Liljedahl

In your time StartResourceUpdateService is missing a field “schedule” for “frequency” field.
Now it looks like:

  frequency: {
    repeat: {'every':300}
  },

But it must be like:

  frequency: {
    schedule: 'custom',

    repeat: {'every':300}
  },

Have you edit it?
You can fix it by adding “schedule” field to the timer

Regards

Hi,

I fixed that timer code. Don’t think it was related, but now I can deploy my Cloud Code also. However my problem seems to be the same.

Looking in the “Show Execution HIstory” window on the timer page, it seems like the timer is continiously running (even before I changed the timer code).

However I get nothing in the Real time logger:

And I don’t get my tables updated from the Cloud Code.

Maybe I’m doing some rookie misstake here, but it all seem to have started when I got the initial error in this thread: Backendless encountered an error while handling an API request.

We logged this error with ID 724A5FF8-DD51-43B4-AA8D-0F269F4D4BF0 and will be investigating the issue.

Looks like you are reaching your daily API request limit for your plan.
About the Free Plan (1000 requests/day)

The timer invokes your API service every 300 seconds, and you hit your limit at about 11:40 a.m. every day.

Sounds odd as I only have 10 rows in my database and the timer therefore hardly uses any requests after the first run. However, should I not be able to see in the real time logger the times the timer has run before 11.40? And even see the cancelled attempts in the real time logger after 11.40?

Your timer invokes the fetchData API service method. Each invocation of that method results in the following:

  1. Running a query against the Realms table - 1 API call (line 81)
  2. For each fetched record, you use 6 API calls to log your data (`console.log). Lines 90-93, 97, 99
  3. For each record, you then update it - 1 API call, line 113
  4. There are additional logging API calls on lines 122 and 125

As a result, every timer invocation results anywhere between 3 and 3+6*number-of-fetched-records

With the daily limit of 1000 API calls, you exhaust all of them by around 17:35 GMT0. The analytics screen shows that with the number of errors you run into:

All the calls that invoked the timer can be seen in the log files:

Once the API limit is reached, the timer will no longer run until the limit is reset the following day.

Regards,
Mark

Alright, thanks. Didn’t reallize there was a 1000 per day limit and didn’t realize console.log was api calls. Now it works, thanks!