0

I'm building an application using Django/Python backend and React/JavaScript frontend. The application is using Axios to import data from another application using an API. I have deployed the application to Heroku and 4 of the 5 imports are working successfully but one is failing on Heroku (but is working locally). The import contains a reasonable amount of data and takes the longest of the 5 imports. Can anyone help me pin down the problem?

This is the error:

createError.js:16 Uncaught (in promise) Error: Request failed with status code 500
    at e.exports (createError.js:16)
    at e.exports (settle.js:17)
    at XMLHttpRequest.f.onreadystatechange (xhr.js:59)

This is the React component:

import React, { Component } from 'react'
import axios from 'axios'
import { formatTimeDate } from '../../lib/helpers'

class CrewLoader extends Component {
  constructor() {
    super()

    this.state = {
      loading: false,
      crewDataUpdated: ''
    }

    this.getData = this.getData.bind(this)

  }

  async getData() {
    this.cancelTokenSource = axios.CancelToken.source()
    this.setState({ loading: true })

    try {

      const crews = await axios.get('/api/crew-data-import', {
        cancelToken: this.cancelTokenSource.token
      })
      console.log(crews.data)

      this.setState({ crewDataUpdated: Date.now(), loading: false })

    } catch (err) {
      if (axios.isCancel(err)) {
        // ignore
      } else {
        // propegate
        throw err
      }
    } finally {
      this.cancelTokenSource = null
    }
  }
  componentWillUnmount() {
    this.cancelTokenSource && this.cancelTokenSource.cancel()
  }

  render() {
    const { loading } = this.state

    return (
      <div>
        <button className="button is-primary" onClick={this.getData} disabled={loading}>

          {loading && <span className="spinner"><i
            className="fas fa-spinner fa-spin"
          /> Loading ...</span>}
          {!loading && <span>Get Crew data</span>}

        </button>
        <p><small>{!this.state.crewDataUpdated ? '' : `Updated: ${formatTimeDate(this.state.crewDataUpdated)}`}</small></p>
      </div>
    )
  }
}

export default CrewLoader

This is the view.py:

class CrewDataImport(APIView):

    def get(self, _request):
        # Start by deleting all existing crews and times
        Crew.objects.all().delete()
        RaceTime.objects.all().delete()

        Meeting = os.getenv("MEETING2019") # Competition Meeting API from the Information --> API Key menu
        UserAPI = os.getenv("USERAPI") # As supplied in email
        UserAuth = os.getenv("USERAUTH") # As supplied in email

        header = {'Authorization':UserAuth}
        request = {'api_key':UserAPI, 'meetingIdentifier':Meeting}

        url = 'https://webapi.britishrowing.org/api/OE2CrewInformation' # change ENDPOINTNAME for the needed endpoint eg OE2MeetingSetup

        r = requests.post(url, json=request, headers=header)
        if r.status_code == 200:
            # pprint(r.json())

            for crew in r.json()['crews']:

                data = {
                    'name': crew['name'],
                    'id': crew['id'],
                    'composite_code': crew['compositeCode'],
                    'club': crew['clubId'],
                    'rowing_CRI': crew['rowingCRI'],
                    'rowing_CRI_max': crew['rowingCRIMax'],
                    'sculling_CRI': crew['scullingCRI'],
                    'sculling_CRI_max': crew['scullingCRIMax'],
                    'event': crew['eventId'],
                    'status': crew['status'],
                    'bib_number': crew['customCrewNumber'],
                    'band': crew['bandId'],
                }

                serializer = WriteCrewSerializer(data=data)
                serializer.is_valid(raise_exception=True)
                serializer.save()

            crews = Crew.objects.all()
            serializer = WriteCrewSerializer(crews, many=True)
            return Response(serializer.data)

        return Response(status=400)

Project urls:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('django-admin/', admin.site.urls),
    path('auth/', include('rest_framework.urls')),
    path('api/', include('results.urls')),
    path('api/', include('jwt_auth.urls')),
    path('', include('frontend.urls')),
]

sunshine2171
  • 23
  • 1
  • 5

1 Answers1

0

You maybe have CORS issue if you use different urls for frontend and backned. Could you provide more information, example of url for frontend/backend Maybe you can find more addition information inside browser network?

  • Hi there - I've added the urls patterns from the project folder. Is that what you meant? – sunshine2171 Nov 02 '19 at 13:14
  • as for example if you locally run front and back ends it will use localhost:3000 (frontend) and localhost:8080 (backend) so the same url localhost so everything works fine but when you deployed it on server and backend is my-backend.com and frontend is my-frontend.com it will not work if you don't allow CORS or specific domain can you check how to add CORS https://stackoverflow.com/questions/35760943/how-can-i-enable-cors-on-django-rest-framework I have not worked with Python – Oleksandr Paiziak Nov 02 '19 at 13:58
  • Can you check backend error log? there should be more information about 500 error – Oleksandr Paiziak Nov 02 '19 at 15:34
  • Thanks Oleksand. I installed django-cors-header and that fixed it! – sunshine2171 Nov 02 '19 at 17:29
  • You are welcome. Could you check my comment as correct answer :) – Oleksandr Paiziak Nov 02 '19 at 17:46