2015-05-16 11 views
6

Próbuję przesłać obraz do S3, ale kiedy zadzwonię do s3.putObject (params, callback), mój callback nigdy nie zostanie wywołany i żadne błędy nie są rejestrowane.S3.putObject - wywołanie zwrotne nigdy nie jest wywoływane

Oto odpowiedni kod:

var params = { 
    Key: key, 
    Body: imageData, 
    ContentLength: imageData.byteCount, 
    ContentType: contentType, 
}; 
this.s3.putObject(params, function(err, data) { 
    console.log('here'); 
    if (err) { 
    callback(err); 
    return; 
    } 
    callback(null, key); 
}); 

Gdzie params jest { Key: 'e2f99bf3a321282cc7dfaef69fe8ca62.jpg', Body: {imageData parsed from request using node-multiparty}, ContentLength: 27802, ContentType: 'image/jpeg', }

I sprawdzeniu, że this.s3 jest ważna i typeof this.s3.putObject jest funkcja, jak oczekiwano.

+0

Możesz uzyskać pewien wgląd, instalując i wymagając modułu 'nock' od npm, który wydrukuje dokładnie, jaki adres URL jest wymagany. Jeśli program zawiesza się czekając na wywołanie zwrotne, być może zapora ignoruje próbę połączenia TCP. Czy pozwalasz programowi zawieszać się na kilka minut, aby sprawdzić, czy w końcu skończy się limit czasu, a następnie zostanie wywołane wywołanie zwrotne? –

+0

Czy twój program kończy wykonywanie zanim zdarzenie async może zwrócić wartość? Zobacz podobny temat z AWS Lambda: https://stackoverflow.com/questions/28449363/why-is-this-http-request-not-working-on-aws-lambda –

Odpowiedz

3

Jeśli kod ten jest używany dla funkcji lambda trzeba dodać context.done() wewnątrz funkcji zwrotnej na putObject jest tak:

 s3.putObject(params, function(err, data) { 
      if (err) console.log(err, err.stack); // an error occurred 
      else  console.log(data);   // successful response 
      context.done(); 
     }); 

Wymusza wykonanie czekać aż zwrotna jest wypełniona przed to wychodzi. Aby to działało, musisz usunąć również context.succeed lub context.done z głównej procedury obsługi, jeśli ją masz.

+0

Co to jest "kontekst" w tym ... um ... kontekst? Nie jest nigdzie zadeklarowany w kodzie ani oryginalnym pytaniu. –

+0

Ah, dobry punkt @boutell. Założyłem, że to pytanie odnosi się do używania AWS Lambda, chociaż nie mówi tego wprost. Zmienię moją odpowiedź, aby to odzwierciedlić. Kontekst jest obiektem specyficznym dla lambda. Jeśli używasz Lambda, konieczne jest wywołanie metody zakończenia kontekstu (done, succeed, fail) w funkcji callback, aby umożliwić jej zakończenie. Jeśli nie jest to kod Lambda, to używany program kończy działanie przed zakończeniem oddzwaniania. – Charles

+0

Dzięki za wyjaśnienie! Możesz napisać "AWS Lambda" tylko dlatego, że funkcje lambda mają bardziej ogólne znaczenie. –

0

Mam dokładnie to samo zachowanie z wszystkimi prawami IAM i straciłem trochę czasu, zanim dostałem go do pracy.

Jeśli twoja funkcja lambda działa wewnątrz VPC, musisz utworzyć punkt końcowy dla S3 zgodnie z opisem w this article from AWS blog.

Jeśli chcesz zobaczyć więcej szczegółów, gdzie się zawiesza, możesz użyć następującego kodu. Zamiast podawać wywołanie zwrotne, zachowaj odwołanie na żądanie i zasadniczo obserwuj jego zdarzenia (patrz dokumentacja: S3.putObject i AWS.Request).

var obj = s3.putObject(params); 
obj.on('validate',    (...args)=>{args.unshift('validate');    console.log(...args);}) 
    .on('build',    (...args)=>{args.unshift('build');    console.log(...args);}) 
    .on('sign',     (...args)=>{args.unshift('sign');     console.log(...args);}) 
    .on('send',     (...args)=>{args.unshift('send');     console.log(...args);}) 
    .on('retry',    (...args)=>{args.unshift('retry');    console.log(...args);}) 
    .on('extractError',   (...args)=>{args.unshift('extractError');   console.log(...args);}) 
    .on('extractData',   (...args)=>{args.unshift('extractData');   console.log(...args);}) 
    .on('success',    (...args)=>{args.unshift('success');    console.log(...args);}) 
    .on('error',    (...args)=>{args.unshift('error');    console.log(...args);}) 
    .on('complete',    (...args)=>{args.unshift('complete');    console.log(...args);}) 
    .on('httpHeaders',   (...args)=>{args.unshift('httpHeaders');   console.log(...args);}) 
    .on('httpData',    (...args)=>{args.unshift('httpData');    console.log(...args);}) 
    .on('httpUploadProgress', (...args)=>{args.unshift('httpUploadProgress'); console.log(...args);}) 
    .on('httpDownloadProgress', (...args)=>{args.unshift('httpDownloadProgress'); console.log(...args);}) 
    .on('httpError',   (...args)=>{args.unshift('httpError');   console.log(...args);}) 
    .on('httpDone',    (...args)=>{args.unshift('httpDone');    console.log(...args);}) 
    .send(); 

Robiąc tak muszę zobaczyć żądania HTTP bazowy starał się dotrzeć do publiczne adresy wiadra, co nie jest możliwe z VPC chyba że masz punkt końcowy :).

Oto kolejny wpis dotyczący dostępu do zasobów AWS z VPC również z AWS blog.

Powiązane problemy